Java SimpleDateFormat时区转换异常:JDK8升级JDK17后结果不符
问题原因与解决方案
问题根源
JDK 17对TimeZone.getTimeZone()的时区解析逻辑及内置时区数据库做了调整:
- JDK 8中,传入"PST"会自动映射到美国太平洋时区(
America/Los_Angeles),该时区包含夏令时规则,因此夏令时期间会显示PDT(UTC-7),时间计算符合预期。 - JDK 17中,"PST"被识别为固定偏移的UTC-8时区(无夏令时切换),导致时间计算采用了错误的偏移量,最终返回不符合预期的结果。
另外你的代码存在一处笔误:方法内定义的Date对象是d,但format方法传入的是未定义的date,不过这不是引发时区问题的核心原因。
修复方案
放弃使用过时的SimpleDateFormat和Date类,改用JDK 8引入的java.time现代日期时间API,它的时区处理更规范可靠:
import java.time.Instant; import java.time.ZoneId; import java.time.format.DateTimeFormatter; public String format(long epochTimeInMS, String timeZone) { Instant instant = Instant.ofEpochMilli(epochTimeInMS); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm z"); return formatter.format(instant.atZone(ZoneId.of(timeZone))); }
调用时建议使用标准时区ID(比如America/Los_Angeles)替代"PST"作为参数,这样无论JDK版本如何,都能正确识别带夏令时规则的时区,返回对应的时区缩写(PDT或PST)。如果必须保留"PST"作为输入,可在代码中做映射处理:
ZoneId zoneId = "PST".equals(timeZone) ? ZoneId.of("America/Los_Angeles") : ZoneId.of(timeZone);
内容的提问来源于stack exchange,提问作者robin
相关产品推荐
相关产品推荐

