Java: How to display weekday, month and date and no year in locale sensitive manner

眉间皱痕 提交于 2020-05-08 15:42:09

问题


In my app I need to display dates in a locale-sensitive manner. So "Thursday, May 10, 2018" should display as is in en_US but should display as "Thursday, 10 May 2018" in en_GB (English Great Britain).

In most cases I can use the following style of code with java.time API classes:

public String toString(ZonedDateTime input) {
    DateTimeFormatter dateTimeFormatter = getDateTimeFormatter(FormatStyle.MEDIUM, FormatStyle.SHORT);
    return input.format(dateTimeFormatter);
}

private DateTimeFormatter getDateTimeFormatter(FormatStyle dateStyle, FormatStyle timeStyle) {
    String pattern = DateTimeFormatterBuilder.getLocalizedDateTimePattern(
            dateStyle, timeStyle, IsoChronology.INSTANCE, Locale.getDefault());

    return DateTimeFormatter.ofPattern(pattern);
}

In such cases I do not specify an explicit date pattern but instead specify a symbolic FormatStyle.

I am not sure of the best way to handle case where there is no standard FormatStyle that meets my needs.

A concrete example is where I need to show Day of Week, Month and Date but no year.

So "Thursday, May 10, 2018" should display as "Thursday, May 10" in en_US but should display as "Thursday, 10 May" in en_GB (English Great Britain).

Any suggestions on how to handle this requirement?


回答1:


    String formatPattern = DateTimeFormatterBuilder.getLocalizedDateTimePattern(
            FormatStyle.FULL, null, IsoChronology.INSTANCE, loc);
    formatPattern = formatPattern.replaceFirst("^.*?([MLdEec].*[MLdEec]).*$", "$1");
    DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(formatPattern, loc);
    System.out.println(LocalDate.now(ZoneId.of("Pacific/Johnston")).format(dateFormatter));

Output with loc equal to Locale.US:

Thursday, May 10

And with Locale.UK (Great Britain):

Thursday, 10 May

How it works: I start out from a localized format pattern string. In my regular expression I am recognizing format pattern letters that have to do with month (ML), day of month (d) and day of week (Eec). I am keeping the substring from the first to the last of such letters. The leading reluctant quantifier .*? makes sure I get the first matching letter. If some locale puts the year somewhere between those wanted elements, it will end up being included.

I am feeling I am being overly creative. Please test with all the test examples you can think of before deciding that you want something like this.




回答2:


You can use

DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM)

which will use the default system locale. If you want to choose an explicit locale (for testing), then then you can use withLocale.

DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM)
    .withLocale(Locale.US);

Here's an example:

DateTimeFormatter pattern = DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM)
    .withLocale(Locale.US);

System.out.println(
    LocalDate.of(1999, 1, 1).format(pattern)
);

Output: Jan 1, 1999

If I change the locale to Locale.UK the output becomes 1 Jan 1999


To obtain the day of week, you can use

DayOfWeek.from(myDate).getDisplayName(TextStyle.FULL, Locale.getDefault())

and then just concatenate the strings. (Again, play with the Locale to see different results. Locale.GERMAN gives you Freitag)




回答3:


Try to localize the date formatter:

DateTimeFormatter pattern = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL).withLocale(Locale.US);


来源:https://stackoverflow.com/questions/50277395/java-how-to-display-weekday-month-and-date-and-no-year-in-locale-sensitive-man

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!