【发布时间】:2021-12-24 00:52:07
【问题描述】:
为了提高一些遗留代码的性能,我正在考虑用 java.time.format.DateTimeFormatter 替换 java.text.SimpleDateFormat。
执行的任务包括解析使用 java.util.Date.toString 序列化的日期/时间值。使用 SimpleDateFormat,可以将它们转换回原始时间戳(忽略小数秒),但是在尝试对 DateTimeFormatter 执行相同操作时遇到问题。
当使用任何一种格式进行格式化时,我的本地时区将显示为 CET 或 CEST,具体取决于夏令时是否对要格式化的时间有效。但是,在解析时,DateTimeFormatter 似乎将 CET 和 CEST 视为相同。
这会在夏令时结束时产生重叠问题。格式化时, 02:00:00 创建两次,时间间隔一小时,但使用 CEST 和 CET 时区名称 - 这很好。但在解析时,无法回收这种差异。
这是一个例子:
long msecPerHour = 3600000L;
long cet_dst_2016 = 1477778400000L;
DateTimeFormatter formatter =
DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss zzz yyyy", Locale.ENGLISH);
ZoneId timezone = ZoneId.of("Europe/Berlin");
for (int hours = 0; hours < 6; ++hours) {
long time = cet_dst_2016 + msecPerHour * hours;
String formatted = formatter.format(Instant.ofEpochMilli(time).atZone(timezone));
long parsedTime = Instant.from(formatter.parse(formatted)).toEpochMilli();
System.out.println(formatted + ", diff: " + (parsedTime - time));
}
导致
Sun Oct 30 00:00:00 CEST 2016, diff: 0
Sun Oct 30 01:00:00 CEST 2016, diff: 0
Sun Oct 30 02:00:00 CEST 2016, diff: 0
Sun Oct 30 02:00:00 CET 2016, diff: -3600000
Sun Oct 30 03:00:00 CET 2016, diff: 0
Sun Oct 30 04:00:00 CET 2016, diff: 0
它表明第二次出现的 02:00:00,尽管时区名称不同,但被视为第一次出现。所以结果实际上是关闭了一小时。
显然,格式化字符串包含所有可用信息,SimpleDateFormat 解析实际上尊重了它。是否可以使用给定模式使用 DateTimeFormatter 进行格式化和解析往返?
【问题讨论】: