Java 17中ZonedDateTime解析UTC时区失败的解决方案问询
问题:兼容GMT/UTC前缀时区偏移的日期时间解析异常
现有代码可正常解析格式为"2022-12-29 01:16:03 GMT+08:00"的字符串:
public ZonedDateTime parseZonedDateTime(String timeStr) { DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss O"); ZonedDateTime zonedDateTime = ZonedDateTime.parse(timeStr, dtf); return zonedDateTime; }
但解析"2022-12-29 01:16:03 UTC-08:00"时,会抛出异常:
java.time.format.DateTimeParseException: Text '2022-12-29 01:16:03 UTC-08:00' could not be parsed at index 20
根据DateTimeFormatter文档,GMT+08:00和UTC-08:00都属于本地化时区偏移格式O,尝试使用格式"yyyy-MM-dd HH:mm:ss OOOO"后问题依旧。虽有资料称该问题在Java 9 build b116中已修复,但在Java 17.0.4.1-librca版本中仍存在,需要找到能同时兼容GMT和UTC输入的正确解析模式。
解决方案
可以通过DateTimeFormatterBuilder构建支持两种前缀的解析格式,明确兼容GMT和UTC开头的时区偏移字符串:
public ZonedDateTime parseZonedDateTime(String timeStr) { DateTimeFormatter dtf = new DateTimeFormatterBuilder() // 日期时间部分 .appendPattern("yyyy-MM-dd HH:mm:ss ") // 可选的GMT或UTC前缀 .appendOptional(DateTimeFormatter.ofPattern("GMT")) .appendOptional(DateTimeFormatter.ofPattern("UTC")) // 时区偏移部分(匹配+08:00或-08:00格式) .appendPattern("XXX") .toFormatter(); return ZonedDateTime.parse(timeStr, dtf); }
或者采用更简洁的可选模式语法(方括号包裹可选部分):
public ZonedDateTime parseZonedDateTime(String timeStr) { DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss [GMT][UTC]XXX"); return ZonedDateTime.parse(timeStr, dtf); }
这两种方式的核心是将GMT/UTC作为可选前缀处理,再用XXX匹配标准时区偏移格式(±HH:mm),避开O模式的兼容性问题,同时兼容两种前缀的输入。
如果需要临时快速兼容,也可以先将字符串中的UTC替换为GMT再解析,这种方式更简单但不够优雅:
public ZonedDateTime parseZonedDateTime(String timeStr) { DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss O"); return ZonedDateTime.parse(timeStr.replace("UTC", "GMT"), dtf); }
内容的提问来源于stack exchange,提问作者Leil Jan C
相关产品推荐
相关产品推荐

