Java中如何解析可变精度带时区的日期字符串并格式化?
解决Java中解析带可变长度小数秒与时区偏移的日期字符串问题
你的代码报错核心原因有两个:
SimpleDateFormat的SSS仅支持三位毫秒,无法解析字符串中的6位微秒282551;- 时区格式
Z要求四位偏移(如-0600),但你的字符串是两位的-06,格式不匹配。
而且SimpleDateFormat本身线程不安全,Java 8之后官方推荐使用java.time包下的新日期API,它能完美处理可变长度小数秒和灵活的时区偏移。
正确实现代码
import java.time.OffsetDateTime; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatterBuilder; import java.time.temporal.ChronoField; public class Ejemplos { public static void main(String[] args) { // 测试不同格式的输入字符串 String[] testDates = { "2022-11-08 10:28:04.282551-06", // 6位小数 "2022-11-08 10:28:04.282-06", // 3位小数 "2022-11-08 10:28:04.28-06", // 2位小数 "2022-11-08 10:28:04-06" // 无小数 }; // 构建支持0-6位小数秒+多格式时区偏移的格式化器 DateTimeFormatter parser = new DateTimeFormatterBuilder() .appendPattern("yyyy-MM-dd HH:mm:ss") .optionalStart() // 小数部分为可选 .appendFraction(ChronoField.NANO_OF_SECOND, 0, 6, true) // 匹配0-6位小数 .optionalEnd() .appendPattern("XX") // 兼容-06、-0600、+08:00等时区格式 .toFormatter(); for (String fecha : testDates) { OffsetDateTime odt = OffsetDateTime.parse(fecha, parser); // 格式化为去掉时区、保留原小数精度的目标格式 String result = odt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss[.SSSSSS]")); System.out.println(result); } } }
代码说明
DateTimeFormatterBuilder允许定义可选格式段(optionalStart()/optionalEnd()),让小数部分可存在可不存在;appendFraction(ChronoField.NANO_OF_SECOND, 0, 6, true)直接支持0到6位的小数秒,完美适配你提到的各种精度情况;XX格式可以自动识别两位(-06)、四位(-0600)、带冒号(-06:00)等多种时区偏移格式;- 最后格式化时使用
[.SSSSSS]保留原有的小数秒长度,不会强制补零或截断。
运行输出
2022-11-08 10:28:04.282551 2022-11-08 10:28:04.282 2022-11-08 10:28:04.28 2022-11-08 10:28:04
内容的提问来源于stack exchange,提问作者JACGV
相关产品推荐
相关产品推荐

