2016-03-23 1 views
17

В настоящее время у меня есть парсер Joda date, который использует DateTimeFormatterBuilder с полдюжины различных форматов дат, которые я могу получить.Java 8 Дата, эквивалентная DateTimeFormatterBuilder от Joda с несколькими форматами парсера?

Я перехожу к процедурам даты Java 8 и не вижу эквивалента.

Как я могу сделать что-то подобное с помощью Java 8 Dates?

DateTimeParser[] parsers = { 
    DateTimeFormat.forPattern("yyyy/MM/dd HH:mm:ss.SSSSSS").getParser() , 
    DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss").getParser() , 
    DateTimeFormat.forPattern("ddMMMyyyy:HH:mm:ss.SSS Z").getParser() , 
    DateTimeFormat.forPattern("ddMMMyyyy:HH:mm:ss.SSS").getParser() , 
    DateTimeFormat.forPattern("ddMMMyyyy:HH:mm:ss.SSSSSS").getParser() , 
    DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss.SSS").getParser() 
}; 

DateTimeFormatter dateTimeFormatterInput = new DateTimeFormatterBuilder() 
    .append(null, parsers).toFormatter(); 
+0

Вы, вероятно, наблюдать серьезное снижение производительности мудры - особенно если вы планируете для реализации замены путем обработки исключений. По моим собственным испытаниям, Joda-Time быстрее. См. Также [JDK-issue] (https://bugs.openjdk.java.net/browse/JDK-8152273). –

ответ

16

Для этого нет прямого средства, но вы можете использовать необязательные разделы. Дополнительные секции заключены в квадратные скобки []. Это позволяет исключить весь раздел строки.

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("" 
    + "[yyyy/MM/dd HH:mm:ss.SSSSSS]" 
    + "[yyyy-MM-dd HH:mm:ss[.SSS]]" 
    + "[ddMMMyyyy:HH:mm:ss.SSS[ Z]]" 
); 

Этот форматтер определяет 3 дополнительных дополнительных раздела для трех основных шаблонов, которые у вас есть. Каждый из них находится внутри своего необязательного раздела.

Работа демо-код:

public static void main(String[] args) { 
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("" 
     + "[yyyy/MM/dd HH:mm:ss.SSSSSS]" 
     + "[yyyy-MM-dd HH:mm:ss[.SSS]]" 
     + "[ddMMMyyyy:HH:mm:ss.SSS[ Z]]" 
    , Locale.ENGLISH); 
    System.out.println(LocalDateTime.parse("2016/03/23 22:00:00.256145", formatter)); 
    System.out.println(LocalDateTime.parse("2016-03-23 22:00:00", formatter)); 
    System.out.println(LocalDateTime.parse("2016-03-23 22:00:00.123", formatter)); 
    System.out.println(LocalDateTime.parse("23Mar2016:22:00:00.123", formatter)); 
    System.out.println(LocalDateTime.parse("23Mar2016:22:00:00.123 -0800", formatter)); 
} 
+0

Если язык тоже меняется, то этот код не будет работать. –

+0

Обратите внимание, что вы не можете использовать это для форматирования, а только для разбора. При форматировании с использованием такого форматирования вы получите все форматы. Я предполагаю, что если вы хотите несколько дополнительных форматов и один «по умолчанию» для отображения, вам нужно использовать два разных экземпляра «DateTimeFormatter» - один с дополнительными форматами, используемыми для синтаксического анализа, и один с только форматом по умолчанию для отображения. – Itai

8

В качестве альтернативного ответа на Tunaki, вы можете также использовать DateTimeFormatterBuilder:

DateTimeFormatter dateFormatter = new DateTimeFormatterBuilder() 
    .appendPattern("[yyyy]") 
    .appendPattern("[M/d/yyyy]") 
    .parseDefaulting(ChronoField.MONTH_OF_YEAR, 1) 
    .parseDefaulting(ChronoField.DAY_OF_MONTH, 1) 
    .toFormatter() 
+1

У меня не получилось работать с несколькими приложениями. Я создал список DateTimeFormaters и цикл с try/catch. – Avec

2

Перебор @ решение Tunaki, используя потоки, когда код нужно принять различные шаблоны конфигурируемым образом:

DateTimeFormatter dateTimeFormatter = dateFormats.stream() 
     .map(DateTimeFormatter::ofPattern) 
     .reduce(new DateTimeFormatterBuilder(), 
       DateTimeFormatterBuilder::appendOptional, 
       (f1, f2) -> f1.append(f2.toFormatter())) 
     .toFormatter(); 

В этом случае мне не нужна комбинаторная часть редуктора, но мне нужна его в сигнатуре, поэтому я сделал комбинатор правильным.

Этот код будет практически эквивалентно, если вышеуказанные модели (yyyy/MM/dd HH:mm:ss.SSSSSS, yyyy-MM-dd HH:mm:ss[.SSS], ddMMMyyyy:HH:mm:ss.SSS[ Z]) будет подаваться в поток:

DateTimeFormatter formatter = new DateTimeFormatterBuilder() 
    .appendOptional(DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss.SSSSSS") 
    .appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss[.SSS]" 
    .appendOptional(DateTimeFormatter.ofPattern("ddMMMyyyy:HH:mm:ss.SSS[ Z]") 
    .toFormatter(); 

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

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