Проверка 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