Разбор даты не в формате UTC с DateTimeFormatterBuilder - PullRequest
0 голосов
/ 01 мая 2019

Я пытаюсь проанализировать следующую строку даты, полученную из полезной нагрузки события Bitbucket :

2017-09-19T10:39:36+1000

Когда входящая дата находится в смещении +0000, тогда она работает, но +1000 не.

Это немного нестандартная (с точки зрения JDK) строка даты, в которой в смещении нет двоеточия.Поэтому я создал пользовательский DateTimeFormatter, который работает, когда смещение равно +0000:

DateTimeFormatter formatter = new DateTimeFormatterBuilder()
    .append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
    .optionalStart()
    .appendOffset("+HHMM", "+0000")
    .optionalEnd()
    .toFormatter();

Однако, когда смещение равно +1000, как указано выше, происходит сбой с:

Невозможно десериализовать значение типа java.time.OffsetDateTime из строки «2017-09-19T10: 39: 36 + 1000»: не удалось десериализовать java.time.OffsetDateTime: (java.time.format.DateTimeParseException) Text '2017-09-19T10: 39: 36 + 1000 'не удалось проанализировать по индексу 19

Если в полученной строке даты используется смещение +0000, то это работает.Как я могу проанализировать все часовые пояса?

Обновление - Дополнительный контекст:

Используется для создания экземпляра JavaTimeModule, используемого для информирования ObjectMapper о формате входящей даты:

JavaTimeModule javaTimeModule = new JavaTimeModule();
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
    .append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
    .optionalStart()
    .appendOffset("+HHMM", "+0000")
    .optionalEnd()
    .toFormatter();
// This also fails:
// DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssx");
LocalDateTimeDeserializer deserializer = new LocalDateTimeDeserializer(formatter);
javaTimeModule.addDeserializer(LocalDateTime.class, deserializer);
// MAPPER is an instance of com.fasterxml.jackson.databind.ObjectMapper
MAPPER.registerModule(javaTimeModule);

Ответы [ 2 ]

0 голосов
/ 01 мая 2019

Шаблон Z может анализировать это смещение.Вы пытались использовать это:

DateTimeFormatter formatter = new DateTimeFormatterBuilder()
        .append(ISO_LOCAL_DATE_TIME)
        .appendPattern("Z")
        .toFormatter();

Он может анализировать +0000 и +1000.

0 голосов
/ 01 мая 2019

Для анализа +1000 этот код будет работать.

package com.iamninad.qa;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class TimeFormat {

    public static void main(String[] args) throws IOException {
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ");
        System.out.println(dateTimeFormatter.parse("2017-09-19T10:39:36+1000"));
        LocalDateTimeDeserializer deserializer = new LocalDateTimeDeserializer(dateTimeFormatter);

        JavaTimeModule javaTimeModule = new JavaTimeModule();
        javaTimeModule.addDeserializer(LocalDateTime.class, deserializer);
        ObjectMapper MAPPER = new ObjectMapper();
        MAPPER.registerModule(javaTimeModule);

        // serialize object

        String s = MAPPER.writeValueAsString(new Data());
        System.out.println(s);

        // deserialize object

        String json = "{\"date\":\"2017-09-19T10:39:36-0830\"}";
        String json1 = "{\"date\":\"2017-09-19T10:39:36+1000\"}";

        Data data = MAPPER.readValue(json, Data.class);
        System.out.println(data.toString());

        Data data1 = MAPPER.readValue(json1, Data.class);
        System.out.println(data1.toString());
    }

}

class Data {
    // Just to generate a sample data
    private DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ");
    private LocalDateTime date = LocalDateTime.parse("2017-09-19T10:39:36+1000", dateTimeFormatter);

    public LocalDateTime getDate() {
        return date;
    }

    public void setDate(LocalDateTime date) {
        this.date = date;
    }

    @Override
    public String toString() {
        return "Data{" +
                "date=" + date +
                '}';
    }
}

Если вы хотите проанализировать +10: 00, тогда используйте ISO_OFFSET_DATE_TIME для полей в формате +10: 00 или шаблон yyyy-MM-dd'T'HH:mm:ssXXX.быть в любом одном формате.Я думаю, что эта проблема решена в jdk 9

OffsetDateTime.parse("2017-09-19T10:39:36+10:00")

Также анализирует время только в одном формате, т.е. +10: 00, а не в +1000, вам нужно указать форматер для parse метод

OffsetDateTime.parse("2017-09-19T10:39:36+1000",DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZZZ"))
...