Java 8 - 尝试使用文本时区 ID 解析时间戳
Java 8 - Trying to parse timestamp with textual TimeZone ID
呃...我这辈子都想不通。我正在使用 Java 8 并尝试做一些像解析时间戳一样简单的事情,其中时区 ID 是文本值,例如 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
有谁知道如何解析时区 ID 作为文本值出现的时间戳?
有两个问题:
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 不是区域的标准格式并且不受支持。您可以通过以下方式查看支持的时区:
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);
这应该有效。
呃...我这辈子都想不通。我正在使用 Java 8 并尝试做一些像解析时间戳一样简单的事情,其中时区 ID 是文本值,例如 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
有谁知道如何解析时区 ID 作为文本值出现的时间戳?
有两个问题:
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 不是区域的标准格式并且不受支持。您可以通过以下方式查看支持的时区:
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);
这应该有效。