Java 8 - Попытка разобрать метку времени с текстовым идентификатором TimeZone - PullRequest
0 голосов
/ 05 января 2019

Тьфу ... Я не могу понять это для моей жизни. Я использую Java 8 и пытаюсь сделать что-то столь же простое, как синтаксический анализ отметки времени, где ID TimeZone является текстовым значением, таким как HST:

РАБОТЫ

ZonedDateTime timestamp = ZonedDateTime.parse("2018-10-29T12:00:12.456-10:00");

НЕ РАБОТАЕТ

ZonedDateTime timestamp = ZonedDateTime.parse("2018-10-29T12:00:12.456HST");

И получите эту ошибку:

java.time.format.DateTimeParseException: Text '2018-10-29T12:00:12.456HST' could not be parsed at index 23

Кто-нибудь знает, как проанализировать метку времени, когда идентификатор часового пояса входит в текстовое значение?

1 Ответ

0 голосов
/ 05 января 2019

Есть две проблемы:

1) Метод ZonedDateTime.parse разбирает только строки, соответствующие формату ISO_ZONED_DATE_TIME, описание того, как это выглядит, вы можете найти здесь: https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#ISO_ZONED_DATE_TIME

Чтобы проанализировать ваш формат, вы должны создать свой собственный dateTimeFormatter.

Этот форматер может выглядеть так

DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .parseCaseInsensitive()
            .append(DateTimeFormatter.ISO_LOCAL_DATE)
            .appendLiteral('T')
            .append(DateTimeFormatter.ISO_LOCAL_TIME)
            .appendZoneId()
            .toFormatter();

Этот форматер будет работать, если вы будете использовать стандартные зоны, такие как GMT, UTC и т. Д. Проблема в том, что HST не является стандартным форматом для Zone и не поддерживается. Вы можете увидеть поддерживаемые часовые пояса через:

System.out.println(ZoneId.getAvailableZoneIds());

Если вы все еще хотите использовать зону HST, вы должны добавить ZoneRulesProvider для своей пользовательской зоны, например:

  ZoneRulesProvider.registerProvider(new ZoneRulesProvider() {
        @Override
        protected Set<String> provideZoneIds() {
            return Collections.singleton("HST");
        }

        @Override
        protected ZoneRules provideRules(String zoneId, boolean forCaching) {
            return ZoneRules.of(ZoneOffset.ofHours(10));
        }

        @Override
        protected NavigableMap<String, ZoneRules> provideVersions(String zoneId) {
            TreeMap map =  new TreeMap<>();
            map.put("HST",ZoneRules.of(ZoneOffset.ofHours(10)));
            return  map;
        }
    });

    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .parseCaseInsensitive()
            .append(DateTimeFormatter.ISO_LOCAL_DATE)
            .appendLiteral('T')
            .append(DateTimeFormatter.ISO_LOCAL_TIME)
            .appendZoneId()                
            .toFormatter();

    ZonedDateTime timestamp = ZonedDateTime.parse("2018-10-29T12:00:12.456HST", formatter);
    System.out.println(timestamp);

Это должно сработать.

...