Java时区问题
一、常见时区
| 时区 | 偏移量 | 夏令时 | 解释 |
| UTC | +00:00 | 无 | 协调世界时,是国际标准的时间基准,基于原子钟的精确时间。 |
| GMT | +00:00 | 无 | 格林尼治标准时间,基于英国伦敦格林尼治天文台的本初子午线(经度 0°)的时间标准。Java 中 GMT 和 UTC 可以视为等价,但建议优先使用 UTC,因为UTC更准 |
| Asia/Shanghai | UTC+8 或者GMT+8 | 无 | 中国大陆地区时间,也就是我们常说北京时间 |
| America/New_York | UTC-5 或 UTC-4 | 有 | 纽约时间 |
| Europe/London | UTC+0 或 UTC+1 | 有 | 伦敦时间 |
我们关注前三个就行。如果你的公司做国际化项目,可能时区就调整成了GMT或者UTC,那么我们在使用时间的时候就要注意时区问题。
二、指定时区
1.使用 java.util.TimeZone(旧版 API)
(1)获取默认时区
TimeZone defaultTimeZone = TimeZone.getDefault();
System.out.println("默认时区: " + defaultTimeZone.getID()); // 例如 Asia/Shanghai
(2) 为 SimpleDateFormat 指定时区
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
sdf.setTimeZone(TimeZone.getTimeZone("UTC")); // 设置为 UTC
System.out.println("UTC 时间: " + sdf.format(new Date()));
(3)为 Calendar 指定时区
Calendar calendar = Calendar.getInstance();
calendar.setTimeZone(TimeZone.getTimeZone("Asia/Tokyo"));
System.out.println("东京时间: " + calendar.getTime());
2.使用 java.time.ZoneId(新版 API,Java 8+ 推荐)
(1) 获取默认时区
ZoneId defaultZone = ZoneId.systemDefault();
System.out.println("默认时区: " + defaultZone); // 例如 Asia/Shanghai
(2) 转换时区
ZonedDateTime utcTime = ZonedDateTime.now(ZoneId.of("UTC"));
ZonedDateTime shanghaiTime = utcTime.withZoneSameInstant(ZoneId.of("Asia/Shanghai"));
System.out.println("UTC -> 上海: " + shanghaiTime);
(3) 使用 ZoneOffset(固定偏移量)
ZoneOffset offset = ZoneOffset.ofHours(8); // UTC+8
OffsetDateTime offsetTime = OffsetDateTime.now(offset);
System.out.println("固定偏移时间: " + offsetTime);
(4)总结
| 场景 | 旧版 API (java.util) |
新版 API (java.time) |
| 获取默认时区 | TimeZone.getDefault() | ZoneId.systemDefault() |
| 设置时区 | TimeZone.setDefault() | 不推荐全局修改,应显式指定 |
| 格式化时区 | SimpleDateFormat.setTimeZone() | DateTimeFormatter.withZone() |
| 转换时区 | Calendar.setTimeZone() | ZonedDateTime.withZoneSameInstant() |
推荐使用 java.time(Java 8+),它线程更安全、更灵活!

浙公网安备 33010602011771号