Разрешается ли двухбуквенный год?

Недавно, после обновления библиотеки Apache POI, я обновил и некоторые другие API. Другая библиотека, которую я использовал, считала все содержимое ячейки как String, а затем мне пришлось проанализировать эту строку в Date.

Проблема возникла, когда пользователь начал вводить дату как dd-mm-yy, а год обозначался как 00yy AD.

Согласно документации SimpleDateFormat

Для синтаксического анализа, если количество букв шаблона превышает 2, год интерпретируется буквально, независимо от количества цифр. Таким образом, используя шаблон "MM/dd/yyyy", "01/11/12" анализирует до 11 января 12 года нашей эры.

Итак, вопрос в том, лучше ли вводить четырехбуквенный год вместо двухбуквенного года?

Другой вопрос, каков наилучший способ предсказать год, если он в двухбуквенном формате. Так как проблема придет при разборе ниже года

Bond Start Date : 12-Jan-98 (1998)
Bond End Date   : 12-Jan-70 (2070)

С уважением, Хануман

1 ответ

Решение

Не понятно, о чем вы спрашиваете.

  1. Если вы спрашиваете, как указать формат даты, который принимает двухзначные года (только) и интерпретирует их условно, то вам следует использовать "dd-mm-yy",

  2. Если вы спрашиваете, как указать формат даты, который принимает двухзначные годы и интерпретирует их условно, И ТАКЖЕ обрабатывает 4 (или более) цифр года, то вы не сможете. Как говорит Javadoc, если вы используете "dd-mm-yyyy", 2 цифры года интерпретируются как годы в первом веке нашей эры.

    Одним из возможных решений является использование ДВУХ форматов. Первая попытка разбора с помощью "dd-mm-yy"и если это не удается, попробуйте "dd-mm-yyyy",

    Но это хак... и проблематично, если пользователю действительно нужно ввести историческую дату.

  3. Если вы спрашиваете, что делать, то я бы порекомендовал отойти от неоднозначных специальных форматов, которые заставляют вас (эффективно) угадывать, что пользователь имеет в виду.

    • Если пользователь должен вводить дату / время в символьной форме, потребуйте от него использования одного из форматов ISO 8601 и будьте строги при анализе предоставленных пользователем строк даты / времени.

    • В противном случае предоставьте пользователю виджет выбора даты.


Другой вопрос, каков наилучший способ предсказать год, если он в двухбуквенном формате.

Ну, это суть проблемы, не так ли? В 20 веке мы все знали, что означает год с двумя цифрами. Ты только что ударил 19 по фронту. (Ах... это были старые добрые времена!)

Теперь необходимо использовать другую эвристику. И эвристика, которая SimpleDateFormat использует описывается javadoc таким образом:

"Для анализа с сокращенным шаблоном года ("y"или"yy") SimpleDateFormat должен интерпретировать сокращенный год относительно некоторого столетия. Он делает это, корректируя даты так, чтобы они находились в пределах 80 лет до и 20 лет после времени экземпляра SimpleDateFormat Например, при использовании шаблона "MM/dd/yy" и экземпляра SimpleDateFormat, созданного 1 января 1997 г., строка "01/11/12" будет интерпретироваться как 11 января 2012 г., а строка "05/04/64"будет интерпретироваться как 4 мая 1964 года".

Эвристика - от 80 до 20 лет после "сейчас". Таким образом, на самом деле 12 января-98 в 1998 году, а 12-января-70 в 1970 году... если вы анализируете с помощью SimpleDateFormat с форматом "уу".

Если вам нужно, чтобы даты означали что-то другое, вам нужно использовать другой анализатор дат. Например, если вы используете библиотеки Joda-time, можно указать "сводный год"; т.е. средний год столетия, в который попадают 2-значные годы.

Ссылка:

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