2015-09-10 4 views
6

Если я использую шаблон, такой как d/M/yy для создания Java 8 DateTimeFormatter (например, используя DateTimeFormatter.ofPattern(pattern); (который я буду использовать только для синтаксического анализа, а не для форматирования), он будет интерпретировать все двухбуквенные годы как 20xx, например, разбор строки, такой как 13/5/99, интерпретироваться как 2099-05-13, что в моем случае неверно (оно должно было быть в 1999 году).Как изменить базовую дату для синтаксического анализа двухбуквенных лет с помощью Java 8 DateTimeFormatter?

В моем приложении я пытаюсь разобрать даты из документов OCR'd, которые могут, например, 90-е годы, поэтому наличие старого поведения SimpleDateFormat для интерпретации даты в течение 80 лет до и через 20 лет после текущей даты подходит мне довольно хорошо. Но по разным причинам я все еще хочу переключить всю логику синтаксического анализа на новую Java 8 DateTimeFormatters.

Просматривая исходный код Java, я вижу, что все это интерпретируется относительно константы ReducedPrinterParser.BASE_DATE, но я не вижу способа изменить значение, используемое при построении собственного форматирования из шаблона. Разве это просто невозможно, или я пропустил какую-то возможность указать поведение для разбора двухбуквенных лет?

+0

Возможный дубликат [Синтаксический строку местная дата не использует желаемый век] (http://stackoverflow.com/questions/29490893/parsing-string-to-local-date-doesnt-use-desired-century) –

ответ

9

Вы можете создать собственный форматировщик, например, для d/M/yy шаблона: Использование

new DateTimeFormatterBuilder() 
     .appendPattern("d/M/") 
     .appendValueReduced(ChronoField.YEAR_OF_ERA, 2, 2, LocalDate.now().minusYears(80)) 

Пример:

public static void main(String[] args) throws Exception { 
    DateTimeFormatter fmt = new DateTimeFormatterBuilder() 
      .appendPattern("d/M/") 
      .appendValueReduced(ChronoField.YEAR_OF_ERA, 2, 2, LocalDate.now().minusYears(80)) 
      .toFormatter(); 
    parse("13/5/99", fmt); 
    parse("13/5/36", fmt); 
    parse("13/5/35", fmt); 
    parse("13/5/34", fmt); 
    parse("13/5/33", fmt); 
} 

private static void parse(String date, DateTimeFormatter fmt) { 
    System.out.println(date + " = " + LocalDate.parse(date, fmt)); 
} 

, который печатает:

13/5/99 = 1999-05-13
13/5/36 = 1936-05-13
13/5/35 = 1935-05-13
13/5/34 = 2034-05-13
13/5/33 = 2033-05-13

+0

Немного громоздко (поскольку у меня будет в основном проанализировать мой существующий список шаблонов, проверить, содержит ли он «yy», а затем построить форматтер, как вы описали), но его определенно выполнимо, спасибо, я не знал, что могу объединить часть шаблона с другими параметрами как это! – David

+2

О, и намек на то, что люди наткнулись на ту же проблему: appendValueReduced (ChronoField.YEAR_OF_ERA, 2, 4, LocalDate.now(). MinusYears (80)) дает вам возможность анализировать как двухсимвольные, так и четырехсимвольные годы ! – David

 Смежные вопросы

  • Нет связанных вопросов^_^