SimpleDateFormat pattern based on locale, but forc

2019-04-08 13:01发布

I need to build a date format like dd/MM/yyyy. It's almost like DateFormat.SHORT, but contains 4 year digits.

I try to implement it with

new SimpleDateFormat("dd//MM/yyyy", locale).format(date);

However for US locale the format is wrong.

Is there a common way to format date that changes pattern based on locale?

Thank you

4条回答
乱世女痞
2楼-- · 2019-04-08 13:22

java.time

Here’s the modern answer. IMHO these days no one should struggle with the long outdated DateFormat and SimpleDateFormat classes. Their replacement came out in the modern Java date & time API early in 2014, the java.time classes.

I am just applying the idea from Happier’s answer to the modern classes.

The DateTimeFormatterBuilder.getLocalizedDateTimePattern method generates a formatting pattern for date and time styles for a Locale. We manipulate the resulting pattern string to force the 4-digit year.

LocalDate date = LocalDate.of( 2017, Month.JULY, 18 );

String formatPattern =
    DateTimeFormatterBuilder.getLocalizedDateTimePattern(
        FormatStyle.SHORT, 
        null, 
        IsoChronology.INSTANCE, 
        userLocale);
formatPattern = formatPattern.replaceAll("\\byy\\b", "yyyy");
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(formatPattern, userLocale);

String output = date.format(formatter);

Example output:

  • For Locale.US: 7/18/2017.
  • For each of UK, FRANCE, GERMANY and ITALY: 18/07/2017.

DateTimeFormatterBuilder allows us to get the localized format pattern string directly, without getting a formatter first, that’s convenient here. The first argument to getLocalizedDateTimePattern() is the date format style. null as second argument indicates that we don’t want any time format included. In my test I used a LocalDate for date, but the code should work for the other modern date types too (LocalDateTime, OffsetDateTime and ZonedDateTime).

查看更多
够拽才男人
3楼-- · 2019-04-08 13:25

I would do it like this:

    StringBuffer buffer = new StringBuffer();

    Calendar date = Calendar.getInstance();
    DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.SHORT, Locale.US);
    FieldPosition yearPosition = new FieldPosition(DateFormat.YEAR_FIELD);

    StringBuffer format = dateFormat.format(date.getTime(), buffer, yearPosition);
    format.replace(yearPosition.getBeginIndex(), yearPosition.getEndIndex(), String.valueOf(date.get(Calendar.YEAR)));

    System.out.println(format);

Using a FieldPosition you don't really have to care about wheter the format of the date includes the year as "yy" or "yyyy", where the year ends up or even which kind of separators are used.

You just use the begin and end index of the year field and always replace it with the 4 digit year value and that's it.

查看更多
可以哭但决不认输i
4楼-- · 2019-04-08 13:31

I have similar way to do this, but I need to get the locale pattern for the ui controller.

So here's the code

            // date format, always using yyyy as year display
        DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.SHORT, locale);
        SimpleDateFormat simple = (SimpleDateFormat) dateFormat;
        String pattern = simple.toPattern().replaceAll("\\byy\\b", "yyyy");
        System.out.println(pattern);
查看更多
祖国的老花朵
5楼-- · 2019-04-08 13:45

Can you not just use java.text.DateFormat class ?

DateFormat uk = DateFormat.getDateInstance(DateFormat.LONG, Locale.UK);
DateFormat us = DateFormat.getDateInstance(DateFormat.LONG, Locale.US);

Date now = new Date();
String usFormat = us.format(now);
String ukFormat = uk.format(now);

That should do what you want to do.

查看更多
登录 后发表回答