Java: как отображать день недели, месяц и дату, а не год, в зависимости от языка - PullRequest
0 голосов
/ 10 мая 2018

В моем приложении мне нужно отображать даты в зависимости от языка. Поэтому «четверг, 10 мая 2018 года» должен отображаться как «en_US», но должен отображаться как «четверг, 10 мая 2018 года» в en_GB (английский, Великобритания).

В большинстве случаев я могу использовать следующий стиль кода с классами API java.time:

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);
}

В таких случаях я не указываю явный шаблон даты, а вместо этого указываю символический FormatStyle.

Я не уверен, что лучше всего справляться со случаем, когда нет стандартного FormatStyle, отвечающего моим потребностям.

Конкретный пример: мне нужно показать день недели, месяц и дату, но не год.

Таким образом, «четверг, 10 мая 2018 года» должен отображаться как «четверг, 10 мая» в en_US, но должен отображаться как «четверг, 10 мая» в en_GB (английский, Великобритания).

Любые предложения о том, как справиться с этим требованием?

Ответы [ 3 ]

0 голосов
/ 10 мая 2018

Вы можете использовать

DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM)

, который будет использовать системную локаль по умолчанию. Если вы хотите выбрать явную локаль (для тестирования), тогда вы можете использовать withLocale.

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

Вот пример:

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

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

Выход: Jan 1, 1999

Если я изменю локаль на Locale.UK, вывод будет 1 Jan 1999


Чтобы получить день недели, вы можете использовать

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

а затем просто объединить строки. (Опять же, поиграйте с Locale, чтобы увидеть другие результаты. Locale.GERMAN дает вам Freitag)

0 голосов
/ 10 мая 2018
    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));

Выход с loc, равным Locale.US:

Четверг, 10 мая

А с Locale.UK (Великобритания):

четверг, 10 мая

Как это работает: я начинаю с локализованной строки шаблона формата. В моем регулярном выражении я распознаю буквы шаблонов формата, которые имеют отношение к месяцу (ML), дню месяца (d) и дню недели (Eec). Я сохраняю подстроку от первой до последней такой буквы. Ведущий квантификатор неохотно .*? гарантирует, что я получу первое соответствующее письмо. Если какой-то язык поместит год где-то между этими элементами, он будет включен.

Я чувствую, что я чрезмерно креативен. Пожалуйста, протестируйте все примеры тестов, которые вы можете придумать, прежде чем решить, что вам нужно что-то подобное.

0 голосов
/ 10 мая 2018

Попробуйте локализовать форматировщик даты:

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