为何使用SimpleDateFormat解析Java纪元时间会偏差30分钟?
问题根源
你遇到的问题核心是SimpleDateFormat没有正确识别字符串中的'Z'时区标记:
- 代码里把模式中的
Z用单引号包裹成了'Z',这会让SimpleDateFormat把Z当成普通字符处理,完全忽略它代表UTC时区的含义。 - 解析时默认使用了本地时区来处理这个时间字符串,而你的开发机器本地时区在1970年1月1日当天,和UTC存在30分钟的偏移量,导致解析出的时间对应的纪元毫秒数出现了30分钟的差值。
修复方案
方案1:修正SimpleDateFormat的使用
调整模式并指定UTC时区,让SimpleDateFormat正确解析Z标记:
public long determineMysteriousMachineTimeDelta() { String strDateOfEpochStart = "1970-01-01T00:00:00Z"; // 去掉Z的单引号,让格式识别时区标记 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); // 强制指定UTC时区,避免本地时区干扰 format.setTimeZone(TimeZone.getTimeZone("UTC")); Date dateStartOfEpoch = null; try { dateStartOfEpoch = format.parse(strDateOfEpochStart); } catch (ParseException e) { return -1; } return dateStartOfEpoch.getTime(); // 现在会返回0 }
方案2:使用Java 8+的新日期API(推荐)
SimpleDateFormat是线程不安全且设计老旧的类,推荐用java.time包下的API,更简洁可靠:
public long determineMysteriousMachineTimeDelta() { String strDateOfEpochStart = "1970-01-01T00:00:00Z"; try { // Instant直接解析带Z的UTC时间字符串,toEpochMilli()返回纪元毫秒数 return Instant.parse(strDateOfEpochStart).toEpochMilli(); } catch (DateTimeParseException e) { return -1; } }
内容的提问来源于stack exchange,提问作者Adam Wise
相关产品推荐
相关产品推荐

