Java 8如何将Instant按ISO 8601格式化为带时区偏移的日期字符串
问题原因
格式化结果异常是因为模式字符串存在多处字段误用、冗余配置:
- 日期字段匹配错误:
YYYY对应ISO周历的周计年份,不是通用公历年,公历年需使用小写yyyy;DD对应当年的天数序号(例如6月21日是当年第172天,输出结果里的异常数字172就来自这个字段的错误匹配),要匹配月内日期需使用小写dd - 时间字段匹配错误:
hh对应12小时制小时(取值范围1-12),ISO 8601标准使用24小时制,需用大写HH匹配 - 冗余分隔符:秒值后额外添加了字面量
'T',标准格式中T仅作为日期和时间的中间分隔符出现一次,时间与时区偏移之间不需要该字符 - 时区格式错误:
ZD是无效组合,末尾的D会被识别为“当年天数”字段拼接到时区偏移后;要输出带冒号分隔的时区偏移(如-05:00),需使用XXX模式匹配。
修复方案
方案1:自定义匹配模式
修正后的模式字符串为yyyy-MM-dd'T'HH:mm:ssXXX,代码实现:
DateTimeFormatter formatter = DateTimeFormatter .ofPattern("yyyy-MM-dd'T'HH:mm:ssXXX") .withZone(ZoneId.systemDefault()); // 输出格式示例:2022-06-21T13:31:49-05:00,和预期格式完全一致 String standardTime = formatter.format(Instant.now());
方案2:使用JDK内置标准格式化器(推荐)
JDK原生提供了符合ISO 8601规范的带偏移量日期时间格式化器,无需手动拼接模式,容错性更高:
DateTimeFormatter formatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME .withZone(ZoneId.systemDefault()); // 输出格式示例:2022-06-21T13:31:49.234-05:00,默认携带毫秒精度 String standardTime = formatter.format(Instant.now());
如果不需要毫秒/纳秒精度,选择方案1的自定义模式即可。
内容的提问来源于stack exchange,提问作者OTUser
相关产品推荐
相关产品推荐

