Java 8-尝试使用文本时区ID解析时间戳

Java 8-尝试使用文本时区ID解析时间戳,java,timestamp,timezone,zoneddatetime,Java,Timestamp,Timezone,Zoneddatetime,啊。。。我一辈子都搞不懂这个。我正在使用Java 8并尝试做一些简单的事情,比如解析一个时间戳,其中时区ID是一个文本值,例如HST: 工作 ZonedDateTime时间戳=ZonedDateTime.parse2018-10-29T12:00:12.456-10:00 不起作用 ZonedDateTime时间戳=ZonedDateTime.parse2018-10-29T12:00:12.456HST 并获取以下错误: java.time.format.DateTimeParseExcept

啊。。。我一辈子都搞不懂这个。我正在使用Java 8并尝试做一些简单的事情,比如解析一个时间戳,其中时区ID是一个文本值,例如HST:

工作

ZonedDateTime时间戳=ZonedDateTime.parse2018-10-29T12:00:12.456-10:00

不起作用

ZonedDateTime时间戳=ZonedDateTime.parse2018-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格式的字符串,有关其外观的说明可在此处找到:

为了解析格式,您必须创建自己的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 zone,则必须为自定义分区添加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);

这应该行得通。

,如果可以避免解析三个字母的时区缩写,请尝试。它们不是标准化的,所以不能保证你得到什么。虽然HST可能仅表示夏威夷标准时间,但最常用的缩写词(包括PST、CST和EST)不明确。HST似乎在此处受支持,并且似乎是太平洋/檀香山的同义词。您可以使用HST,但Java ZoneId不支持HST,因为它是非标准的,您可以在此处找到更多信息:。Java希望整个字符串Pacific/Honolulu用作ZoneId,如果要将HST用作ZoneId,则必须注册自己的ZoneRuleProviderRight。这不是氮氧化物。但这是一个公认的区域名称。只需使用DateTimeFormatter.ofpatternyyyyy-MM-dd'HH:MM:ss.sssz就可以解析字符串。看。理想情况下,发布这些字符串的发布者应该了解如何使用正确的时区名称,如Pacific/Honolulu。