Java dateformat незаконный шаблонный символ 'y'
В последнее время у нас возникла странная ошибка в рабочей среде (тестовые среды отлично работают).
java.lang.IllegalArgumentException: символ нелегального шаблона 'y'
Это вызвано следующим кодом
SimpleDateFormat dateFormat = (SimpleDateFormat)DateFormat.getDateInstance();
dateFormat.applyLocalizedPattern("yyyy-MM-dd");
Эта ошибка обычно возникает, если, например, использовать "Y" вместо "y" в течение года. Это не так, как вы можете видеть выше. Я не уверен на 100% от локали, установленной на сервере. Linux env LANG установлен на "de_DE.UTF_8", поэтому это, вероятно, используется.
Ввод исходного кода SimpleDateFormat.java Я нашел метод translatePattern(String pattern, String from, String to)
. Это исключает упомянутое исключение, если какой-либо символ из pattern
не существует. Значения выглядят как это при отладке локально на другом компьютере
pattern = "yyyy-MM-dd"
from = "GyMdkHmsSEDFwWahKzZ"
Из исключения на сервере видно, что первый "y" не существует в from
. from
извлекается из formatData.getLocalPatternChars()
, который является DateFormatSymbols
, инициализированным из локали на сервере.
Доступны ли даже локали, которые могут иметь форматы без 'y'? Эта ошибка началась без какого-либо изменения кода, и, насколько мне известно, изменение конфигурации сервера не было.
Ответы
Ответ 1
Из SimpleDateFormat javadoc:
SimpleDateFormat также поддерживает локализованный шаблон даты и времени строки. В этих строках шаблонные буквы, описанные выше, могут быть заменены на другие, зависящие от языка, шаблонные буквы.
В вашем случае местным является DE, поэтому локализованный шаблон будет jjjj-MM-tt
. J
обозначает Jahr и T
для Tage.
Если вы не хотите иметь дело с локализованным шаблоном, просто используйте SimpleDateFormat.applyPattern( "yyyy-MM-dd" ).
Ответ 2
В идеале вы должны применять локали шаблона, иначе ваш шаблон должен измениться для разных локалей, поскольку yyyy работает для en_US, jjjj для de_DE и т.д. Вместо этого укажите только yyyy и locale как en_US независимо от языка вашей машины.
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH);
System.out.println(format.format(new java.util.Date()));
Как говорит javadoc:
Создает SimpleDateFormat с использованием заданного шаблона и значения по умолчанию символы формата даты для данного языка. Примечание. Этот конструктор может не поддерживает все локали. Для полного охвата используйте методы factory в класс DateFormat.
Параметры:
pattern: шаблон, описывающий формат даты и времени
locale: язык, в котором должны использоваться символы формата даты
Таким образом, вам не нужно беспокоиться о том, какая локальная строка выбирает локаль выполнения и принудительно применяет конкретный языковой стандарт.