Мне нужно получить OffsetDateTime из строки

Строка имеет следующий формат - «2021-07-13 05: 22: 18.712».

Я пробовал использовать этот код для его анализа. OffsetDateTime parsedDateTime = OffsetDateTime.parse("2021-07-13 05:22:18.712");

Но я продолжаю получать эту ошибку - org.threeten.bp.format.DateTimeParseException: текст '2021-07-13 05:22:18.712' не может быть проанализирован с индексом 10.

Как заставить его работать? Любые предложения будут полезны. Спасибо

2 ответа

Решение

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

      private static final DateTimeFormatter FORMATTER = new DateTimeFormatterBuilder()
        .append(DateTimeFormatter.ISO_LOCAL_DATE)
        .appendLiteral(' ')
        .append(DateTimeFormatter.ISO_LOCAL_TIME)
        .toFormatter(Locale.ROOT);

С этим форматером это довольно простая операция:

          ZoneId zone = ZoneId.of("Asia/Kolkata");
    String input = "2021-07-13 05:22:18.712";
    
    OffsetDateTime dateTime = LocalDateTime.parse(input, FORMATTER)
            .atZone(zone)
            .toOffsetDateTime();
    
    System.out.println(dateTime);

Вывод из фрагмента примера:

2021-07-13T05:22:18.712+05:30

Поскольку, как отметил @Sweeper в комментарии, ваша строка не содержит смещения UTC или часового пояса, проанализируйте ее в первую очередь. В Localв некоторых именах классов java.time означает без часового пояса или смещения UTC. Затем преобразовать в ZonedDateTime в предполагаемом часовом поясе и далее в желаемый тип, OffsetDateTime.

Если вы хотите использовать часовой пояс JVM по умолчанию, установите zone к ZoneId.systemDefault(). Имейте в виду, что часовой пояс по умолчанию может быть изменен в любое время из другой части вашей программы или другой программы, работающей в той же JVM, так что это ненадежно.

Возможные ярлыки

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

      private static final DateTimeFormatter FORMATTER
        = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SSS", Locale.ROOT);

Или, что еще короче, вы можете вручную заменить пробел в своей строке на, чтобы получить формат ISO 8601, а затем проанализировать его в LocalDateTime без указания какого-либо средства форматирования.

Что пошло не так в вашем коде?

Сообщение об исключении, которое вы получили, пытается быть полезным:

Но я продолжаю получать эту ошибку -org.threeten.bp.format.DateTimeParseException: текст '2021-07-1305:22:18.712' не может быть проанализирован с индексом 10.

Индекс 10 в вашей строке - это место, где находится пробел между датой и временем. Один аргумент OffsetDateTime.parse метод ожидает формат ISO 8601, например 2021-07-13T05:22:18.712+05:30, поэтому с a для обозначения начала временной части и со смещением UTC в конце. Отсутствие Tвызвало ваше исключение. Если бы вы это исправили, у вас было бы другое исключение из-за отсутствия смещения UTC.

Статья в Википедии: ISO 8601

Сначала нужно проверить документ .

Это указывает на необходимость синтаксического анализа в формате даты, например 2007-12-03 T 10:15:30 +01: 00 .

В вашей дате отсутствует буква "T", "2021-07-13 05: 22: 18.712". Следовательно, он не прошел, считая его от индекса 0, это символ в 10.

Если вам нужно разобрать 2021-07-13T05: 22: 18.712 , вы все равно получите ошибку. Не удалось проанализировать текст ошибки «2021-07-13T05: 22: 18.712» в индексе 23. Это проблема миллисекунд.

Итак, впереди большой раунд:

      //Format to date
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); 
//Format to new string
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX"); 
java.util.Date date1=simpleDateFormat.parse("2021-07-13 05:22:18.712");
String newDate = formatter.format(date1);

//finally.    
OffsetDateTime parsedDateTime = OffsetDateTime.parse(newDate);
Другие вопросы по тегам