问题
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