DateTimeFormatter обработка коротких месяцев сентября/сентябряJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 DateTimeFormatter обработка коротких месяцев сентября/сентября

Сообщение Anonymous »

В CLDR v38 аббревиатура en_GB для сентября была изменена с «Сентябрь» на «Сентябрь».

Это означает, что начиная с Java 16 в Locale.UK короткое имя теперь «Сентябрь».
Это хорошо известно - согласно этому вопросу SO, этому отчету об ошибке OpenJDK, даже этому отчету об ошибке CLDR.
Мой вопрос заключается в том, как лучше всего справиться с этим вопросом. это особенно важно, если нет уверенности в том, в каком языковом стандарте будет отформатирована дата. Например, я имею дело с поставщиком данных, который предоставляет даты в формате дд/МММ/гггг, но иногда мы получаем короткие названия месяцев в США, например «сентябрь»; а в других случаях мы получаем короткие названия месяцев в Великобритании — например, «Сентябрь».
  • Простое решение — найти и заменить:
Самое простое решение — заменить экземпляры «Sept» на «Sep» перед использованием DateTimeFormatter. Что-то вроде этого, которое может обрабатывать как «09/сентябрь/2009», так и «09/сентябрь/2009»:

Код: Выделить всё

DateTimeFormatter format = DateTimeFormatter.ofPattern("dd/MMM/yyyy").withLocale(Locale.US);
LocalDate date = LocalDate.parse(dateString.replaceAll("Sept", "Sep"), format);
Это кажется неэлегантным, потому что нам приходится очищать входные данные перед использованием DateTimeFormatter, а именно это мы и хотим сделать для форматирования/анализа dateString. С другой стороны, то, что делается, достаточно ясно и читаемо.
  • DateTimeFormatterBuilder — необязательные форматы, каждый из которых указывает локаль:
Я надеялся, что комбинация необязательных форматов будет работать.
Примерно так:

Код: Выделить всё

DateTimeFormatter format = new DateTimeFormatterBuilder()
.appendOptional(DateTimeFormatter.ofPattern("dd/MMM/yyyy").withLocale(Locale.US))
.appendOptional(DateTimeFormatter.ofPattern("dd/MMM/yyyy").withLocale(Locale.UK))
.toFormatter()
.withLocale(Locale.US);
LocalDate d = LocalDate.parse(dateString, format);
К сожалению, это не работает. Если мы не установим локаль для объединенного DateTimeFormatter, он будет использовать ваш локальный локаль, поэтому для согласованности я установил для него значение US. Однако здесь происходит то, что локаль в необязательных DateTimeFormatters игнорируется, и учитывается только локаль
Я не знаю, является ли это предполагаемым поведением или нет. Я думаю, что Javadocs вводит в заблуждение по этому поводу, поскольку они утверждают:

Форматировщик будет форматировать, если данные доступны для всех полей, содержащихся в нем. Средство форматирования выполнит анализ совпадения строки, в противном случае ошибка не будет возвращена.

К сожалению, этого не происходит. Любой необязательный DateTimeFormatter применяется с общим языковым стандартом, а не с примененным к нему языковым стандартом. Затем, если строка dateString имеет короткий месяц в соответствии с одним из этих языков, но который отличается от языка общего параметра DateTimeFormatter, будет выдано исключение.
  • DateTimeFormatter — необязательные символы:
Другая возможность — использовать необязательные символы в шаблоне DateTimeFormatter. Например, при этом будут проанализированы оба коротких названия месяцев: «Сентябрь» и «Сентябрь», хотя это довольно специфично для данного случая.

Код: Выделить всё

DateTimeFormatter format = DateTimeFormatter.ofPattern("dd/MMM['t']/yyyy").withLocale(Locale.US);
LocalDate date = LocalDate.parse(dateString, format);
Кроме того, это возможно только при синтаксическом анализе. Если используется для печати, к короткому названию месяца всегда добавляется необязательная буква «t». Это означает, что если бы это использовалось с format.format(LocalDate.of(2009,1,1)), оно вернуло бы "01/Jant/2009".
Итак, мои вопросы:
  • Как лучше всего настроить DateTimeFormatter, который может обрабатывать короткие названия месяцев в разных локалях, особенно сентябрь в Locale.US и Locale.UK? (Является ли вариант 1. найти/заменить лучшим, что мы можем сделать?)
  • В варианте 2. работает ли это так, как задумано? Или мне чего-то не хватает в плане объединения DateTimeFormatters с разными локалями? Это ошибка/недокументированное поведение?
  • Для варианта 3. можно ли исключить необязательные символы при печати? (Насколько я понимаю, это не так — см. этот вопрос SO.)


Подробнее здесь: https://stackoverflow.com/questions/798 ... ort-months
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»