Как разобрать смещение с двоеточием, используя DateTimeFormatter? - PullRequest
3 голосов
/ 09 апреля 2019

У меня есть следующая строка: String timeStamp = "2020-01-31 12:13:14 +03:00".И я попытался разобрать его с помощью Java 8 DateTimeFormatter.

DateTimeFormatter formatter = DateTimeFormatter.ofPattern( format );
tmpTimestamp = ZonedDateTime.parse( timeStamp, formatter );

, где format является одним из:

"yyyy-MM-dd' 'HH:mm:ss' 'Z",
"yyyy-MM-dd' 'HH:mm:ss' 'X",
"yyyy-MM-dd' 'HH:mm:ss' 'x",
"yyyy-MM-dd HH:mm:ss Z",
"yyyy-MM-dd HH:mm:ss X",
"yyyy-MM-dd HH:mm:ss x",

Ни один не работает.Всегда я получал DateTimeParseException, указывающий либо на символ '+', либо на символ ':' в подстроке смещения "+03: 00"

Согласно JavaDocs: Класс DateTimeFormatter"+03: 00"должен поддерживаться любым из: Z, X и x.

Итак, вопрос в том, как создать строку форматирования для ее анализа?

Ответы [ 3 ]

3 голосов
/ 09 апреля 2019

Вы должны использовать времена X (yyyy-MM-dd HH:mm:ss XXX):

String timeStamp = "2020-01-31 12:13:14 +03:00";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss XXX");
ZonedDateTime tmpTimestamp = ZonedDateTime.parse(timeStamp, formatter);

Из документов :

Смещение Xи x: Это форматирует смещение, основанное на количестве букв образца.

Одна буква выводит только час, например, «+01», если только минута не равна нулю, в этом случае также выводится минута, например, «+0130».

Две буквы выводят часы и минуты без двоеточия, например «+0130».

Три буквы выводят часы и минуты с двоеточием, например, «+01: 30».

Четыре буквы выводят часы и минуты и необязательную секунду,без двоеточия, например «+013015».

Пять букв выводят часы и минуты и необязательную секунду с двоеточием, например «+01: 30: 15».

Шесть или более букв выбрасывают исключение IllegalArgumentException.

Буква шаблона «X» (верхний регистр) будет выводить «Z», когда смещение для вывода будет нулевым, тогда как буква шаблона «x» (нижний регистр) будет выводить «+00», «+0000»', или' +00: 00 '.

В качестве альтернативы вы можете использовать пять букв (XXXXX), а также вы можете использовать ZZZ или ZZZZZ вместо XXX или XXXXX.

3 голосов
/ 10 апреля 2019

Вам не нужно возиться со строкой шаблона формата.

    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .append(DateTimeFormatter.ISO_LOCAL_DATE)
            .appendLiteral(' ')
            .append(DateTimeFormatter.ISO_LOCAL_TIME)
            .appendLiteral(' ')
            .appendOffsetId()
            .toFormatter();
    String timeStampString = "2020-01-31 12:13:14 +03:00";
    OffsetDateTime dateTime = OffsetDateTime.parse(timeStampString, formatter);
    System.out.println(dateTime);

Это более многословно, но сложнее ошибиться.Я просто собираю форматтер из встроенных частей.Вывод:

2020-01-31T12: 13: 14 + 03: 00

Я также выполняю синтаксический анализ OffsetDateTime вместо ZonedDateTime.Поскольку строка содержит смещение (+03: 00) и отсутствие часового пояса (например, America / Boa_Vista), даже если она, вероятно, будет работать с ZonedDateTime, OffsetDateTime является правильным классом для использования.

3 голосов
/ 09 апреля 2019

Из Javadoc

Смещение Z : форматирует смещение на основе номера шаблона буквы. Одна, две или три буквы выводят часы и минуты, без двоеточия, например «+0130». Выход будет «+0000», когда смещение равно нулю. Четыре буквы выводят полную форму локализованного смещение, эквивалентное четырем буквам Offset-O. Выход будет соответствующий локализованный текст смещения, если смещение равно нулю. Пять буквы выводят час, минуту, с необязательной секундой, если не ноль, с двоеточием. Выводит 'Z', если смещение равно нулю. Шесть или более букв выдает IllegalArgumentException.

Вам нужно 5 Z

String format = "yyyy-MM-dd HH:mm:ss ZZZZZ";

Демо

...