Исключение DateTimeParseException: Текст ‘2020-04-01T08:53:47.000 02:00 00:00’ не удалось разобрать, нераспечатанный текст найден по индексу 29

#java #date #datetime #timezone-offset #datetimeformatter

#java #Дата #дата и время #смещение часового пояса #datetimeformatter

Вопрос:

Получение a DateTimeParseExcpetion при попытке преобразовать строку 2020-04-01T08:53:47.000 02:00 00:00

 String date = "2020-04-01T08:53:47.000 02:00 00:00";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSz");
parsedDate = LocalDateTime.parse(date,formatter).toString();
System.out.println(parsedDate);
 

Комментарии:

1. Что должны означать цифры в этой строке? Похоже, что кто-то добавил дополнительную 00:00 дату и время в формате ISO 8601 со смещением от UTC ( 2020-04-01T08:53:47.000 02:00 ). Я не могу догадаться, почему они это сделали.

Ответ №1:

Ваш шаблон не совпадает с вашей Строкой. Проверьте последнюю часть , где находится 000 02:00 00:00 .

Ваш шаблон таков: SSSz

Если вы попробуете это:

 String date = "2020-04-01T08:53:47.000";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS");
 

Это сработает, потому что ваша дата похожа на ваш шаблон. Обратите внимание, что каждое число в дате тоже входит в шаблон.

Но для вашей даты есть пустое место, что не имеет смысла, поэтому, удалив его, код работает отлично.

 String date = "2020-04-01T08:53:47.000 02:00";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSz");
 

Вывод:

 2020-04-01T08:53:47
 

Обратите внимание, что z это местное время и означает «смещение на нулевой час» или «время зулу» (UTC), и вы можете использовать Locale .

Ответ №2:

Строка 00:00 в конце вашей строки даты и времени для меня не имеет смысла. Проанализируйте строку даты и времени после ее удаления.

 import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        String strDate = "2020-04-01T08:53:47.000 02:00 00:00";
        strDate = strDate.substring(0, strDate.lastIndexOf(' '));
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSz", Locale.ENGLISH);
        LocalDateTime parsedDate = LocalDateTime.parse(strDate, formatter);
        System.out.println(parsedDate);

        OffsetDateTime odt = OffsetDateTime.parse(strDate);
        System.out.println(odt);
        System.out.println(odt.getOffset());
    }
}
 

Вывод:

 2020-04-01T08:53:47
2020-04-01T08:53:47 02:00
 02:00
 

Примечание: вы можете проанализировать вашу строку даты и времени (после чередования 00:00 с конца) OffsetDateTime , чтобы сохранить информацию о смещении зоны.

Ответ №3:

Используйте встроенный форматировщик

Встроенный DateTimeFormatter.ISO_OFFSET_DATE_TIME соответствует той части вашей строки, которую мы можем понять. И он может анализировать только эту часть и игнорировать остальное.

     String date = "2020-04-01T08:53:47.000 02:00 00:00";
    ParsePosition pp = new ParsePosition(0);
    OffsetDateTime odt = OffsetDateTime.from(
            DateTimeFormatter.ISO_OFFSET_DATE_TIME.parse(date, pp));
    
    System.out.println("Date and time: "   odt);
    System.out.println("Unparsed text: "   date.substring(pp.getIndex()));
 

Вывод:

 Date and time: 2020-04-01T08:53:47 02:00
Unparsed text:  00:00
 

Поскольку ваша строка содержит смещение от UTC, OffsetDateTime это правильный класс для анализа. Если бы мы использовали LocalDateTIme , смещение было бы проигнорировано, и мы бы в конечном итоге не знали, при каком смещении время должно было интерпретироваться, то есть мы не могли знать, в какой момент времени это было. С OffsetDateTime точкой во времени все однозначно. Если вы хотите перевести на время в вашем собственном часовом поясе, преобразуйте в ZonedDateTime (все еще нет LocalDateTime ).

     ZonedDateTime timeInMyTimeZone = odt.atZoneSameInstant(ZoneId.systemDefault());
    System.out.println("Date and time: "   timeInMyTimeZone);
 

Пример вывода:

 Date and time: 2020-04-01T11:53:47 05:00[Asia/Aqtobe]
 

Ссылки

Ссылки на документацию: