Символы шаблона Java 10 DateTimeFormatter для периодов добавления "E" и "MMM" - PullRequest
0 голосов
/ 15 октября 2018

Так в Java 8 следующее:

DateTimeFormatter df = DateTimeFormatter.ofPattern("E d MMM yyyy");

При применении таким образом:

LocalDate date = LocalDate.now();
date.format(df);

выдаст что-то вроде этого:

"Available on Thu 30 Aug 2018"

Однакоточно такой же код при запуске в Java 10 производит следующее:

"Available on Thu. 30 Aug. 2018"

Обратите внимание на периоды после разделов дня и месяца ...

Я хорошо знаю, что могу просто заменитьпериоды в строке, но я действительно не хочу этого делать.Мне интересно, почему произошло это изменение и есть ли альтернативный шаблон?

Я не могу найти никаких ссылок на это изменение в Интернете.

РЕДАКТИРОВАТЬ:

В соответствии с ответом Василия ниже, это не проблема версии Java.Это проблема локали.Образ докера с моим кодом работает на американском языке, а мой компьютер на Aus:)

1 Ответ

0 голосов
/ 15 октября 2018

Проверка Locale

Знаки пунктуации и связанные с ними вопросы (аббревиатура, орфография, порядок элементов) определены как часть культурных норм.На Яве эти культурные нормы определены как Locale.

Языковой стандарт изменялся во время выполнения

Одной из возможных проблем является то, что вы запускаете код без явного указания Locale, что означает, что вы неявно полагаетесь на текущий языковой стандарт по умолчанию JVM.Это значение по умолчанию может отличаться в разных средах выполнения.

Зарегистрируйте локаль по умолчанию для проверки.

Locale.getDefault().toString()

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

Определение менялось во время выполнения

Обратите внимание, что в связи с этим произошли серьезные измененияна дату и время локализации с помощью Java 9: ​​ JEP 252. По умолчанию используются данные локали CLDR .По крайней мере для JVM на основе OpenJDK источник информации об этих культурных нормах переключился на хранилище общих языковых данных , предоставляемое Unicode Consortium .

Для конкретного случая, обсуждаемого здесь, при использовании Locale.US мы не видим никакой разницы, как вы можете видеть в примере кода ниже.Но для некоторых локалей вы можете увидеть разницу между Java 8 и более ранними версиями по сравнению с Java 9 и более поздними версиями.

Итак, опять же, мне интересно, была ли другая локаль задействована во втором примере вашего Вопроса.Исправление будет заключаться в том, чтобы явно указать локаль, которую вы или ваш пользователь ожидаете, вместо того, чтобы неявно полагаться на текущее текущее значение по умолчанию JVM (значение по умолчанию может измениться в любой момент во время времени выполнения!).

Невозможно подтвердить проблему

System.out.println( System.getProperty( "java.version" ) );
System.out.println( Locale.getDefault().toString() );

LocalDate ld = LocalDate.of( 2018 , Month.AUGUST , 30 );

Locale locale = Locale.US;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "E d MMM yyyy" , locale );
String output = ld.format( f );

System.out.println( output );

При запуске в Java 10.0.2 через JVM на базе OpenJDK от Azul Systems в IntelliJ 2018.3на MacBook Pro Retina под macOS High Sierra я получаю:

10.0.2

en_US

Чт 30 августа 2018

Для Java 8 см. Тот же код, запущенный в режиме реального времени на IdeOne.com .Имейте в виду, что JVM, используемая в IdeOne.com, привязана только к одной локали, Locale.US.

en_US

1.8.0_112

вывод: чт 30 августа 2018

Австралия

Вотпример того, как ваш вывод является нормой в некоторых других англоязычных регионах, таких как Австралия.

LocalDate ld = LocalDate.of( 2018 , Month.AUGUST , 30 );

Locale locale = new Locale( "en" , "AU" );  // "en-AU" is English Australia.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "E d MMM yyyy" , locale );
String output = ld.format( f );

Чт.30 августа 2018

...