Java 8 - Попытка разобрать метку времени с текстовым идентификатором TimeZone
Тьфу... Я не могу понять это для моей жизни. Я использую Java 8 и пытаюсь сделать что-то столь же простое, как синтаксический анализ отметки времени, где идентификатор 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 ответ
Есть две проблемы:
1) Метод ZonedDateTime.parse анализирует только строки, которые соответствуют формату ISO_ZONED_DATE_TIME, описание того, как он выглядит, вы можете найти здесь: https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html
Чтобы проанализировать ваш формат, вы должны создать свой собственный 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);
Это должно работать.