java.time формат даты в зависимости от локали с 2-значным днем ​​/ месяцем и 4-значным годом

Мне нужно показать дату с 2-значным днем, 2-значным месяцем, 4-значным годом в соответствии с порядком местных жителей. Итак, для April 10th 2020 я хочу показать

  1. для локали США: MM/DD/YYYY -> 04/10/2020
  2. для Великобритании: DD/MM/YYYY -> 10/04/2020
  3. для локали DE (Германия): DD.MM.YYYY -> 10.04.2020

Я безуспешно пробовал следующее:

// this one already fails for DE, because it gives 10.04.20 (only 2 digit years)
myDate?.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT))

// works for DE (gives 10.04.2020), fails for UK as is gives 10 Apr 2020 instead of 10/04/2020
myDate?.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM))

Итак, как я могу получить локально адаптированный формат даты только с 2-значным днем ​​/ месяцем и 4-значным годом? Обратите внимание, что я ищу общее решение, 3 явно указанные здесь локали являются лишь примерами.

На самом деле я использую java.time порт для Android (ThreeTenABP), хотя это не должно иметь значения.


person stefan.at.wpf    schedule 10.04.2020    source источник


Ответы (2)


Боюсь, что потребуется некоторая ручная работа. Например, на Java, потому что это то, что я могу написать:

    Locale formattingLocale = Locale.getDefault(Locale.Category.FORMAT);
    String builtInPattern = DateTimeFormatterBuilder.getLocalizedDateTimePattern(
            FormatStyle.SHORT, null, IsoChronology.INSTANCE,
            formattingLocale);
    String modifiedPattern = builtInPattern.replaceFirst("y+", "yyyy")
            .replaceFirst("M+", "MM")
            .replaceFirst("d+", "dd");
    DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(modifiedPattern, formattingLocale);

    LocalDate myDate = LocalDate.of(2020, Month.APRIL, 10);
    System.out.println(myDate.format(dateFormatter));

Примеры выходных данных в разных регионах:

  • US: 04/10/2020
  • UK: 10/04/2020
  • Германия: 10.04.2020
  • Шведский / sv: 2020-04-10
  • Гонконг / zh-HK: 2020 年 04 月 10 日 (я понятия не имел, правильно ли это)
person Ole V.V.    schedule 11.04.2020

Ответ Ole V.V. работает от Oreo, но многие устройства используют более старые версии Android. Следующее работает в большинстве стран для всех версий Android.

Это выглядит хакерским, но в официальном JavaDoc для DateFormat говорится, что преобразование формата из заводских методов в SimpleDateFormat работает в большинстве стран.

val dateFormat = DateFormat.getDateInstance(DateFormat.SHORT)
if (dateFormat is SimpleDateFormat) {
    val adjustedPattern = dateFormat.toPattern()
            .replace("y+".toRegex(), "yyyy")
            .replace("M+".toRegex(), "MM")
            .replace("d+".toRegex(), "dd")
    dateFormat.applyPattern(adjustedPattern)
}

Вы можете заключить это в блокировку попыток и сделать что-нибудь умное для немногих исключительных стран, где это не работает. Или для них вы можете просто отказаться и использовать их короткий формат по умолчанию. Я почти уверен, что люди могут понять этот формат :-D.

person Marko T    schedule 27.11.2020