Как исправить исключение org.threeten.bp.format.DateTimeParseException?

Я конвертирую время UTC в местное время и сталкиваюсь с ошибкой:

org.threeten.bp.format.DateTimeParseException: текст «Среда, 17 октября, 06:12:19 по Гринвичу + 05:30 2018» не может быть проанализирован по индексу 20

Пожалуйста, скажите любые другие варианты или исправьте это решение.

Это мой код, проверьте его:

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss z yyyy", Locale.ENGLISH);
    String formattedDate = LocalDateTime.parse(UTC_time, formatter)
            .atOffset(ZoneOffset.UTC)
            .atZoneSameInstant(ZoneId.systemDefault())
            .format(formatter);

person Bala sundar k    schedule 17.10.2018    source источник
comment
поделитесь своим кодом   -  person Radesh    schedule 17.10.2018
comment
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(EEE MMM dd HH:mm:ss z yyyy, Locale.ENGLISH); Строка formattedDate = LocalDateTime.parse(UTC_time, форматтер) .atOffset(ZoneOffset.UTC) .atZoneSameInstant(ZoneId.systemDefault()) .format(форматер);   -  person Bala sundar k    schedule 17.10.2018
comment
это мой код, пожалуйста, проверьте его.   -  person Bala sundar k    schedule 17.10.2018
comment
Лучше встроить ваш (красиво отформатированный и аккуратный) код в тело вашего вопроса (я только что его отредактировал).   -  person Amessihel    schedule 17.10.2018
comment
Забавно, на бэкпорте я получаю исключение, подобное вашему, но упомянутый индекс равен 23 (где написано +05:30), а не 20 (где написано GMT).   -  person Ole V.V.    schedule 17.10.2018
comment
Ваш код работает со встроенным java.time на Java 1.8.0_66 и на jdk-11, но не работает с бэкпортом. Может быть, это ошибка в бэкпорте или функция без бэкпорта?   -  person Ole V.V.    schedule 17.10.2018


Ответы (2)


Использовать это

DateTimeFormatter formatter = 
       DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss zzz yyyy", Locale.ENGLISH);

Вы можете использовать эту ссылку, чтобы найти шаблон.

person Radesh    schedule 17.10.2018
comment
Странно, согласно страница проекта: Имена зон: выводит отображаемое имя идентификатора часового пояса. Если количество букв равно одному, двум или трем, то выводится короткое имя. Если количество букв равно четырем, то выводится полное имя. Пять или более букв вызывают исключение IllegalArgumentException. Если да, то z или zzz совпадают. - person Amessihel; 17.10.2018
comment
Понятно, соответствующая часть Locale.ENGLISH (см. этот ответ SO). - person Amessihel; 17.10.2018
comment
@Amessihel дайте нам знать, как - person Radesh; 17.10.2018
comment
я пытаюсь это не повлияло на мой код. он также возвращает org.threeten.bp.format.DateTimeParseException: текст «Пн, 22 октября, 14:15:27 по Гринвичу + 05:30 2018» не может быть проанализирован по индексу 20. - person Bala sundar k; 23.10.2018

Во-первых, кажется, что ваша строка может быть получена в результате вызова toString на старомодном объекте java.util.Date. Если это так, вы можете посмотреть, сможете ли вы получить сам объект Date и преобразовать его с помощью DateTimeUtils (из ThreeTenABP) и избавить себя от всех проблем с разбором.

Во-вторых, ваш код работает со встроенным java.time на моем настольном компьютере, и я не знаю, почему он не работает с бэкпортом. Возможное исправление для бэкпорта:

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss OOOO yyyy", Locale.ENGLISH);
    String inputString = "Wed Oct 17 06:12:19 GMT+05:30 2018";
    String formattedDate = OffsetDateTime.parse(inputString, formatter)
            .atZoneSameInstant(ZoneId.systemDefault())
            .format(formatter);
    System.out.println(formattedDate);

На моем компьютере в часовом поясе Европы/Копенгагена это выводит:

Ср 17 окт 02:42:19 GMT+02:00 2018

РЕДАКТИРОВАТЬ: Хотя не задокументировано, что бэкпорт поддерживает букву шаблона формата O, приведенное выше работает на ThreeTen Backport 1.3.6 на моем Mac. Документированной альтернативой является следующий вариант шаблона формата:

    DateTimeFormatter formatter 
            = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss 'GMT'xxx yyyy", Locale.ROOT);

Если вы предпочитаете аббревиатуру часового пояса, например CEST, а не смещение по Гринвичу, вы можете использовать исходный модуль форматирования для обратного форматирования в строку. Хитрость в том, что OOOO в шаблоне формата анализирует GMT+05:30 и этот стиль смещения GMT или UTC в целом.

Я исправил еще одну ошибку в вашем коде: когда вы анализировали LocalDateTime, вы теряли информацию о часовом поясе или смещении из строки, что приводило к неправильному времени. В частности, когда в строке было GMT+05:30 и вы делали .atOffset(ZoneOffset.UTC), время сбивалось на 5 часов 30 минут. Вместо этого используйте OffsetDateTime для синтаксического анализа (если бы z для имени зоны сработало, вам понадобился бы ZonedDateTime).

Ссылка: Документация org.threeten.bp:format.DateTimeFormatter включая буквы шаблона формата

person Ole V.V.    schedule 17.10.2018
comment
у меня это не работает... и я получаю сообщение об ошибке java.lang.IllegalArgumentException: неизвестный символ шаблона 'O' - person Bala sundar k; 23.10.2018
comment
Извините, я упустил важную деталь: бэкпорт не поддерживает букву шаблона O. Есть и другие возможные решения, возможно, менее элегантные. Я еще раз подумаю и вернусь сюда. - person Ole V.V.; 23.10.2018
comment
эй, мне нужно лучшее решение для преобразования времени UTC в местное время... пожалуйста, скажите, чтобы спасти мои дни... - person Bala sundar k; 23.10.2018
comment
Я считаю, что решил это, @Balasundark. Пожалуйста, смотрите мое редактирование. - person Ole V.V.; 23.10.2018
comment
я удаляю часовой пояс следующим образом (вторник, 23 октября, 11:41:26 2018 г.) ... и мой код работал нормально. - person Bala sundar k; 23.10.2018
comment
Для меня это звучит как шаткое решение, если смещение по Гринвичу может быть чем-то другим, чем вы ожидаете. Удачи с этим. - person Ole V.V.; 23.10.2018