Local DateTime не может быть проанализирован в Java 11

У меня есть код ниже.

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
LocalDateTime myDate =  LocalDateTime.parse("2020-11-16T02:27:39.345Z", formatter);

Но он выдает ошибку ниже во второй строке. Не знаю, почему он жалуется Z

java.time.format.DateTimeParseException: Text '2020-11-16T02:27:39.345Z' could not be parsed at index 23
    at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2046)
    at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1948)
    at java.base/java.time.LocalDateTime.parse(LocalDateTime.java:492)

person SMPH    schedule 16.11.2020    source источник
comment
Для этого формата даты используйте либо "yyyy-MM-dd'T'HH:mm:ss.SSSz", либо "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'".   -  person ernest_k    schedule 16.11.2020
comment
@ernest_k это сработало отлично. Не могли бы вы объяснить причину. Вероятно, добавить в качестве ответа.   -  person SMPH    schedule 16.11.2020
comment
Разница между Z и z описана здесь. 'Z' просто заставляет синтаксический анализатор воспринимать букву буквально.   -  person ernest_k    schedule 16.11.2020
comment
Отвечает ли это на ваш вопрос? ZonedDateTime игнорирует 00 для части ss. Или это? как проанализировать OffsetTime для формата HHmmssZ.   -  person Ole V.V.    schedule 18.11.2020
comment
Вам нужно указать форматтер. Просто используйте Instant.parse("2020-11-16T02:27:39.345Z"); или OffsetDateTime.parse("2020-11-16T02:27:39.345Z"). См. этот вопрос. Если вам нужно время в вашем местном часовом поясе, преобразуйте его в ZonedDateTime, а не в LocalDateTime.   -  person Ole V.V.    schedule 18.11.2020
comment
@ОлеВ.В. Упомянутый ernest_k решил проблему.   -  person SMPH    schedule 25.11.2020
comment
@SMPH Они работают. Но поскольку вы уже убедились, что написание строки шаблона формата сопряжено с ошибками и сопряжено с трудностями — именно поэтому вы задали свой вопрос — и поскольку прекрасный ответ Арвинда Кумара Авинаша показывает, что вам не нужна строка шаблона формата, почему вы хочешь побеспокоить?   -  person Ole V.V.    schedule 26.11.2020
comment
Также LocalDateTime - неправильный класс. Ваша строка сообщает нам о моменте времени, а LocalDateTime не может содержать момент времени. Это немного похоже на сохранение значения long в переменной int: преобразование возможно, но вы теряете важную информацию.   -  person Ole V.V.    schedule 26.11.2020


Ответы (1)


LocalDateTime не имеет информации о часовом поясе или смещении зоны, тогда как ваша строка даты и времени имеет смещение зоны. Буква Z в конце вашей строки даты и времени означает Zulu, то есть смещение зоны UTC. Вы можете разобрать его на OffsetDateTime или ZonedDateTime или Instant напрямую (т.е. без использования пользовательского DateTimeFormatter).

Демонстрация:

import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZonedDateTime;

public class Main {
    public static void main(String[] args) {
        String dateTimeString = "2020-11-16T02:27:39.345Z";
        OffsetDateTime odt = OffsetDateTime.parse(dateTimeString);
        System.out.println(odt);
        ZonedDateTime zdt = ZonedDateTime.parse(dateTimeString);
        System.out.println(zdt);
        Instant instant = Instant.parse(dateTimeString);
        System.out.println(instant);
    }
}

Вывод:

2020-11-16T02:27:39.345Z
2020-11-16T02:27:39.345Z
2020-11-16T02:27:39.345Z
person Arvind Kumar Avinash    schedule 18.11.2020