我在应用程序中使用 JSR 310 DateTime API*,并且需要解析和格式化军事日期时间(称为 DTG 或“日期时间组”)。
我正在解析的格式看起来像这样(使用DateTimeFormatter
):
"ddHHmm'Z' MMM yy" // (ie. "312359Z DEC 14", for new years eve 2014)
如上所述,这种格式相当容易解析。当日期包含与“Z”(祖鲁时区,与 UTC/GMT 相同)不同的时区时,就会出现问题,例如“A”(Alpha,UTC+1:00)或“B”(Bravo,UTC+ 2:00)。看军事时区 http://www.timeanddate.com/time/zones/military获取完整列表。
我如何解析这些时区?或者换句话说,除了文字“Z”之外,我还可以在上面的格式中放入什么,以使其正确解析所有区域?我尝试过使用"ddHHmmX MMM yy"
, "ddHHmmZ MMM yy"
and "ddHHmmVV MMM yy"
,但它们都不起作用(全部都会抛出DateTimeParseException: Text '312359A DEC 14' could not be parsed at index 6
对于上面的例子,解析时)。使用单个V
格式不允许(IllegalArgumentException
当尝试实例化时DateTimeFormatter
).
编辑:似乎这个符号z
如果不是因为下面的问题,可能会起作用。
我还应该提到我已经创建了一个ZoneRulesProvider
包含所有指定区域和正确的偏移量。我已经使用 SPI 机制验证了这些已正确注册,并且我的provideZoneIds()
方法按预期被调用。还是不会解析。作为一个附带问题(编辑:现在这似乎是主要问题),API 不允许使用除“Z”之外的单字符时区 ID(或“区域”)。
例如:
ZoneId alpha = ZoneId.of("A"); // boom
会扔DateTimeException: Invalid zone: A
(甚至无需访问我的规则提供程序来查看它是否存在)。
这是 API 中的疏忽吗?或者我做错了什么?
*)实际上,我正在使用 Java 7 并且三十向后移植 http://www.threeten.org/threetenbp/,但我认为这对于这个问题并不重要。
PS:我当前的解决方法是使用 25 个不同的DateTimeFormatter
s 带有文字区域 id(即"ddHHmm'A' MMM yy"
, "ddHHmm'B' MMM yy"
等),使用RegExp
用于提取区域 ID,并根据区域委托给正确的格式化程序。提供者中的区域 ID 被命名为“Alpha”、“Bravo”等,以允许ZoneId.of(...)
找到区域。有用。但它不是很优雅,我希望有更好的解决方案。