问题现象:java程序获得的时间比系统date命令输出的时间要快一个小时
复现:编写一个CurrentTime.java
文件输出时间、时区等信息
xxxxxxxxxx
import 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"));
}
}
编译并运行
xxxxxxxxxx
javac CurrentTime.java
java CurrentTime # 注意不需要加.class
vim 遇到 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]# date
Mon Aug 4 11:23:25 +08 2025
[root@localhost home]# java CurrentTime
Java 默认时区: Asia/Ulaanbaatar
Java 当前时间 (带时区): 2025-08-04T12:23:32.210+09:00[Asia/Ulaanbaatar]
系统时区 (通过环境变量): null
JVM 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: yes
NTP synchronized: yes
RTC in local TZ: no
DST active: n/a
java获得当前时间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()));
}
}