java中如何处理夏令时?

在国际化的项目中,处理时间时经常会遇到夏令时(BST,British Summer Time)问题,发明夏令时(以及冬令时)主要是为了省电。
 
冷知识:中国历史上也曾经采用过(1986-1991)夏令时,后来因为各种原因,最终取消了这一制度(参见:https://baijiahao.baidu.com/s?id=1700703328355099602&wfr=spider&for=pc
 
但欧美国家仍在广泛使用,以2022年为例:根据网上找到的资料

伦敦 在2022-03-27 ~ 2002-10-30 为夏令时期间。
java中如何知道某个地区,在某个时间点是否处于夏令时呢?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
 * 夏令时测试(by菩提树下的杨过)
 */
@Test
public void testTimeZone() {
    LocalTime time = LocalTime.of(10, 20);
    ZoneId zoneId = ZoneId.of("Europe/London");
 
    // A summer date-time
    ZonedDateTime zdtSummer = ZonedDateTime.of(LocalDate.of(2022, 10, 15), time, zoneId);
    System.out.println(zdtSummer);
 
    // A winter date-time
    ZonedDateTime zdtWinter = ZonedDateTime.of(LocalDate.of(2022, 11, 15), time, zoneId);
    System.out.println(zdtWinter);
}

输出:

2022-10-15T10:20+01:00[Europe/London]
2022-11-15T10:20Z     [Europe/London]

即:2022-10-15 10:20:00 这个时间,对于London来说,时区的offset为+1,即向前拨快了1小时(夏令时)

而2022-11-15 10:20:00 这个时间,London的时区offset为Z(即Zero 零),即没有向前调整(不是夏令时)
通过这个测试,可以看到JDK里已经自带了夏令时的判断。
 
那么问题来了,ZoneId在构建时,要传入“Europe/London”这样的地区标识,JDK里支持多少种这类地区标识呢?

  

输出:

从上面的输出可以看出,要表示中国北京时区对应的ZoneId,ZoneId并不是Asia/Beijing,而是Asia/Shanghai,另外也并非所有时区都是整点的偏移量,有些是半小时,甚至45分钟的,比如:

1
2
GMT+09:30   Australia/Darwin
GMT+05:45   Asia/Kathmandu

另外有一个特殊地区:埃及开罗,2024年才开始实施夏令时,jdk 8版本并不能正确识别

仍然输出的是:

GMT+02:00   Africa/Cairo

有用到这个地区的朋友,需要升级JDK(JDK 21 验证是正确的)

 

posted @   菩提树下的杨过  阅读(2389)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
历史上的今天:
2014-11-13 java:多线程基础之Runnable、Callable与Thread
2014-11-13 mybatis 3.x 缓存Cache的使用
2011-11-13 Emit:动态给一个类型添加Attribute
2009-11-13 silverlight中顺序/倒序异步加载多张图片
2009-11-13 silverlight中如何将string(字符串)写入Resource(资源)?
2009-11-13 silverlight中的几个冷门标记 {x:Null},d:DesignWidth,d:DesignHeight
2008-11-13 WCF与IIS集成Windows身份验证的矛盾
点击右上角即可分享
微信分享提示