且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

使用JSR 310(DateTime API)的军事时区

更新时间:2023-01-17 08:04:48

java.time中,ZoneId不得超过2个字符.具有讽刺意味的是,这是为了保留空间,以便在证明JDK的需求量很大时,可以在将来的JDK版本中添加军用ID.因此,遗憾的是您的提供程序将无法运行,并且无法用这些名称创建您想要的ZoneId实例.

In java.time, the ZoneId is limited to be 2 characters or more. Ironically, this was to reserve space to allow the military IDs to be added in a future JDK release if it proved to be heavily in demand. As such, sadly your provider will not work, and there is no way to create the ZoneId instances you desire with those names.

考虑使用ZoneOffset而不是ZoneId时,解析问题就可以解决了(考虑到军事区是固定偏移量,这是解决问题的好方法).

The parsing problem is soluble once you consider working with ZoneOffset instead of ZoneId (and given that military zones are fixed offsets, that is a good way to look at the problem).

键是方法DateTimeFormatterBuilder.appendText(TemporalField, Map),该方法允许使用您选择的文本将数字字段格式化并解析为文本. ZoneOffset是一个数字字段(该值是偏移量中的总秒数).

The key is the method DateTimeFormatterBuilder.appendText(TemporalField, Map) which allows a numeric field to be formatted and parsed as text, using text of your choice. And ZoneOffset is a numeric field (the value being the total number of seconds in the offset).

在此示例中,我为ZAB设置了映射,但是您需要将它们全部添加.否则,代码很简单,设置了一个可以打印和解析军事时间的格式化程序(使用OffsetDateTime表示日期和时间).

I this example, I've setup the mapping for Z, A and B, but you'd need to add them all. Otherwise, the code is pretty simple, setting up a formatter that can print and parse the military time (use OffsetDateTime for date and time).

Map<Long, String> map = ImmutableMap.of(0L, "Z", 3600L, "A", 7200L, "B");
DateTimeFormatter f = new DateTimeFormatterBuilder()
    .appendPattern("HH:mm")
    .appendText(ChronoField.OFFSET_SECONDS, map)
    .toFormatter();
System.out.println(OffsetTime.now().format(f));
System.out.println(OffsetTime.parse("11:30A", f));