问题现象:java程序获得的时间比系统date命令输出的时间要快一个小时
复现:编写一个CurrentTime.java 文件输出时间、时区等信息
xxxxxxxxxximport java.time.*;import java.util.TimeZone;
public class CurrentTime { public static void main(String[] args) { ZoneId zone = ZoneId.systemDefault(); System.out.println("Java 默认时区: " + zone);
ZonedDateTime zonedTime = ZonedDateTime.now(); System.out.println("Java 当前时间 (带时区): " + zonedTime);
System.out.println("系统时区 (通过环境变量): " + System.getenv("TZ")); System.out.println("JVM user.timezone: " + System.getProperty("user.timezone")); }}编译并运行
xxxxxxxxxxjavac CurrentTime.javajava CurrentTime # 注意不需要加.classvim 遇到 Swap file ".CurrentTime.java.swp" already exists! 退出将此文件删掉再编辑,这可能是上次意外退出,网络卡住然后终端强制退出的情况下很常见。
修改系统时区:
xxxxxxxxxx# 可选,验证 `Asia/Shanghai` 是否存在timedatectl list-timezones | grep -i shanghai# 设置时区为 `Asia/Shanghai`sudo timedatectl set-timezone Asia/Shanghai设置时区为 Asia/Ulaanbaatar,问题复现:
xxxxxxxxxx[root@localhost home]# dateMon Aug 4 11:23:25 +08 2025[root@localhost home]# java CurrentTimeJava 默认时区: Asia/UlaanbaatarJava 当前时间 (带时区): 2025-08-04T12:23:32.210+09:00[Asia/Ulaanbaatar]系统时区 (通过环境变量): nullJVM user.timezone: Asia/Ulaanbaatar[root@localhost home]# timedatectl Local time: Mon 2025-08-04 11:23:38 +08 Universal time: Mon 2025-08-04 03:23:38 UTC RTC time: Mon 2025-08-04 03:23:36 Time zone: Asia/Ulaanbaatar (+08, +0800) NTP enabled: yesNTP synchronized: yes RTC in local TZ: no DST active: n/ajava获得当前时间12:23,而date输出11:23
解决办法1:将Asia/Ulaanbaatar改成Asia/Shanghai
但问题是为什么java对应就 +9 呢?而系统date +8 呢?
可能是java时区数据库未更新到最高版本,可以用这个方法检查是否开启了夏令时:
ximport java.time.*;import java.time.zone.*;
public class CheckJavaTimeZone { public static void main(String[] args) { ZoneId zone = ZoneId.of("Asia/Ulaanbaatar"); ZoneRules rules = zone.getRules(); ZoneOffset currentOffset = rules.getOffset(Instant.now()); System.out.println("Java 中 Asia/Ulaanbaatar 的当前偏移量: " + currentOffset); System.out.println("是否使用夏令时: " + rules.isDaylightSavings(Instant.now())); }}