Дата в формате 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), хотя это не должно иметь значения.

1 ответ

Боюсь, что потребуется некоторая ручная работа. Например, на 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));

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

  • США: 10.04.2020
  • Великобритания: 10.04.2020
  • Германия: 10.04.2020
  • Шведский /sv: 2020-04-10
  • Гонконг/zh-HK: 2020å¹´04月10æ— ¥ (я понятия не имел, правильно ли это)

Ответ Ole VV работает от 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.

Другие вопросы по тегам