2016-03-02 3 views
5

Чтобы правильно обрабатывать xs:dateTime с JAXB, я должен написать свой собственный конвертер от String ->java.time.OffsetDateTime.xsd: dateTime to Java OffsetDateTime

Как указано в определении схемы XML, dateTime был основан на ISO 8601. Я использовал OffsetDateTime.parse(s, DateTimeFormatter.ISO_OFFSET_DATE_TIME) для анализа xs:dateTime, который отлично работает, например.

"2007-12-03T10:15:30+01:00" //or 
"2007-12-03T10:15:30Z" 

К сожалению, в xs:dateTime смещение части is declared optional, поэтому разбор действительного

"2016-03-02T17:09:55" 

бросает DateTimeParseException.

Есть ли DateTimeFormatter для OffsetDateTime, который также обрабатывает unzoned xs:dateTime s (возможно, с часовым поясом по умолчанию)?

ответ

4

Я не думаю, что есть встроенный, но вы можете сделать свой собственный с помощью класса DateTimeFormatterBuilder.

Вы можете указать дополнительный смещенный, заключенный в квадрат скобки, т.е. [XXXXX] (в соответствии "+HH:MM:ss"), то вы можете предоставить по умолчанию смещение (parseDefaulting) в том случае, когда его нет. Если вы хотите по умолчанию установить UTC, вы можете установить 0, чтобы не указывать смещение; и если вы хотите по умолчанию использовать текущее смещение виртуальной машины, вы можете получить ее с помощью OffsetDateTime.now().getLong(ChronoField.OFFSET_SECONDS).

public static void main(String[] args) { 
    String[] dates = { 
     "2007-12-03T10:15:30+01:00", 
     "2007-12-03T10:15:30Z", 
     "2016-03-02T17:09:55", 
     "2016-03-02T17:09:55Z" 
    }; 
    DateTimeFormatter formatter = 
     new DateTimeFormatterBuilder().appendPattern("yyyy-MM-dd'T'HH:mm:ss[XXXXX]") 
             .parseDefaulting(ChronoField.OFFSET_SECONDS, 0) 
             // or OffsetDateTime.now().getLong(ChronoField.OFFSET_SECONDS) 
             .toFormatter(); 
    for (String date : dates) { 
     System.out.println(OffsetDateTime.parse(date, formatter)); 
    } 
} 
1

, чтобы показать мое текущее решение, которое разрешающее незональный формат в системах по умолчанию смещения на данный момент в синтаксическом DATETIME.

public static OffsetDateTime parseDateTime(String s) { 
    if (s == null) { 
     return null; 
    } 
    try { 
     return OffsetDateTime.parse(s, DateTimeFormatter.ISO_OFFSET_DATE_TIME); 
    } catch (DateTimeParseException e) { 
     try { // try to handle zoneless xml dateTime 
      LocalDateTime localDateTime = LocalDateTime.parse(s, DateTimeFormatter.ISO_LOCAL_DATE_TIME); 
      ZoneOffset offset = ZoneId.systemDefault().getRules().getOffset(localDateTime); 
      return OffsetDateTime.of(localDateTime.toLocalDate(), localDateTime.toLocalTime(), offset); 
     } catch (Exception fallbackTryException) { 
      throw e; 
     } 
    } 
} 
+0

Ах, поэтому, когда смещение отсутствует, вы интерпретируете дату-время в часовом поясе JVM. Я думаю, что я бы использовал 'localDateTIme.atZone (ZoneId.systemDefault()). ToOffsetDateTime()'. Разве это немного легче читать? –

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