Threeten DateTimeParseException для OffsetDateTime.parse (String, dateTimeFormatter) - PullRequest
0 голосов
/ 04 мая 2018

Я хотел бы просто сделать DateTimeFormatter для использования в OffsetDateTime парсере. Но я получаю DateTimeParseException:

final DateTimeFormatter ISO_LOCAL_DATE;
ISO_LOCAL_DATE = new DateTimeFormatterBuilder()
    .appendValue(YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
    .appendLiteral('-')
    .appendValue(MONTH_OF_YEAR, 2)
    .appendLiteral('-')
    .appendValue(DAY_OF_MONTH, 2)
    .appendLiteral('T')
    .appendValue(HOUR_OF_DAY,2)
    .appendLiteral(':')
    .appendValue(MINUTE_OF_HOUR,2)
    .appendLiteral(':')
    .appendValue(SECOND_OF_MINUTE,2)
    .toFormatter().withResolverStyle(ResolverStyle.STRICT).withChronology(IsoChronology.INSTANCE);

DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
OffsetDateTime.parse("2012-03-06T00:00:00",ISO_LOCAL_DATE);

Я изучил одну похожую проблему, но там тоже не было подсказки: / В чем проблема с кодом выше? Что делать с Formatter или Threeten lib?

1 Ответ

0 голосов
/ 04 мая 2018

Вы не указали смещение во входных данных.

Это пример даты и времени со смещением:

2012-03-06T00:00+01:00

Пример ZonedDateTime:

2012-03-06T00:00+02:00[Europe/Paris]

Europe/Berlin - здесь можно рассматривать как ZoneId. Но каждая зона может иметь различное смещение для разных времен года (летнее / зимнее время).

Нет однозначного сопоставления между ZoneId и ZoneOffset: Есть ли способ преобразовать ZoneId в ZoneOffset в Java 8?

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

Тогда вы можете получить ZonedDateTime и преобразовать его в OffsetDateTime.

public OffsetDateTime ZonedDateTime.toOffsetDateTime()

Это создает дату и время смещения, используя местное время и дату смещения. Идентификатор зоны игнорируется.

Исправление для вашего случая с указанием ZoneId:

public class Main {
    private static final DateTimeFormatter ISO_LOCAL_DATE = new DateTimeFormatterBuilder()
            .appendValue(YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
            .appendLiteral('-')
            .appendValue(MONTH_OF_YEAR, 2)
            .appendLiteral('-')
            .appendValue(DAY_OF_MONTH, 2)
            .appendLiteral('T')
            .appendValue(HOUR_OF_DAY,2)
            .appendLiteral(':')
            .appendValue(MINUTE_OF_HOUR,2)
            .appendLiteral(':')
            .appendValue(SECOND_OF_MINUTE,2)
            .toFormatter()
            .withResolverStyle(ResolverStyle.STRICT)
            .withChronology(IsoChronology.INSTANCE)
            .withZone(ZoneId.systemDefault()); // or whatever you have

    public static void main(String[] args) {
        ZonedDateTime zonedDateTime = ZonedDateTime.parse("2012-03-06T00:00:00", ISO_LOCAL_DATE);
        System.out.println(zonedDateTime);
        System.out.println(zonedDateTime.toOffsetDateTime());
    }
}

Приблизительная мощность:

2012-03-06T00:00+01:00[Europe/City]
2012-03-06T00:00+01:00

Второй вариант исправления - добавьте offsetId() в ваш компоновщик парсера и укажите смещение для входной строки:

public class Main {
    private static final DateTimeFormatter ISO_LOCAL_DATE = new DateTimeFormatterBuilder()
            .appendValue(YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
            .appendLiteral('-')
            .appendValue(MONTH_OF_YEAR, 2)
            .appendLiteral('-')
            .appendValue(DAY_OF_MONTH, 2)
            .appendLiteral('T')
            .appendValue(HOUR_OF_DAY,2)
            .appendLiteral(':')
            .appendValue(MINUTE_OF_HOUR,2)
            .appendLiteral(':')
            .appendValue(SECOND_OF_MINUTE,2)
            .appendOffsetId()
            .toFormatter()
            .withResolverStyle(ResolverStyle.STRICT)
            .withChronology(IsoChronology.INSTANCE);

    public static void main(String[] args) {
        OffsetDateTime offsetDateTime = OffsetDateTime.parse("2012-03-06T00:00:00+02:00", ISO_LOCAL_DATE);
        System.out.println(offsetDateTime);
    }
}

Выход:

2012-03-06T00:00+02:00

Вы можете указать свой собственный шаблон смещения вместо .appendOffsetId(), например:

.appendOffset("+HH:mm", "Z")

Кстати, есть множество стандартных DateTimeFormatter с, которые вы можете использовать "из коробки" для разбора OffsetDateTime.

public class Main {
    public static void main(String[] args) {
        String offsetStringTime = "2012-03-06T00:00:00+02:00";
        OffsetDateTime offsetDateTime = OffsetDateTime.parse(offsetStringTime);
        OffsetDateTime offsetDateTime2 = OffsetDateTime.parse(offsetStringTime, DateTimeFormatter.ISO_OFFSET_DATE_TIME);
        OffsetDateTime offsetDateTime3 = OffsetDateTime.parse(offsetStringTime, DateTimeFormatter.ISO_ZONED_DATE_TIME);
        System.out.println(offsetDateTime);
        System.out.println(offsetDateTime2);
        System.out.println(offsetDateTime3);
    }
}

Выход:

2012-03-06T00:00+02:00
2012-03-06T00:00+02:00
2012-03-06T00:00+02:00
...