在Java时区增加天数东欧夏令时(EEST)

时间:2012-02-07 21:51:22

标签: java timezone dst

我写了一个Java应用程序,其中我在特定年份的1月1日00:00开始日期。然后我将这一天增加355次并打印出结果。我试图了解时区如何围绕夏令时工作,如果增加1天会将时间从午夜转移到凌晨1点,从而进入夏令时。我的代码如下:

TimeZone tz = TimeZone.getDefault();
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss z");
sdf.setTimeZone(tz);
Calendar cal = Calendar.getInstance(tz);
cal.set(2008, 0, 1, 0, 0, 0);
cal.set(Calendar.MILLISECOND, 0);
for ( int i = 0; i < 355; i++ ) {
    System.out.println(sdf.format(cal.getTime()));
    cal.add(Calendar.DAY_OF_MONTH, 1);
}

在我的默认时区(US Eastern)中运行时,输出看起来像我期望的那样:

01/01/2008 00:00:00 EST
01/02/2008 00:00:00 EST
01/03/2008 00:00:00 EST
01/04/2008 00:00:00 EST
...

当我进入夏令时时,我得到了

03/10/2008 00:00:00 EDT
03/11/2008 00:00:00 EDT
03/12/2008 00:00:00 EDT

当我使用观察东欧夏令时的时区时(在这种情况下,我选择了非洲/开罗时区),我得到了输出:

01/01/2008 00:00:00 EET
01/02/2008 00:00:00 EET
01/03/2008 00:00:00 EET
01/04/2008 00:00:00 EET
01/05/2008 00:00:00 EET

但是当我进入东欧夏季时,我得到:

04/25/2008 01:00:00 EEST
04/26/2008 01:00:00 EEST
04/27/2008 01:00:00 EEST

奇怪的是,当EEST结束时,我仍然得到了

08/29/2008 01:00:00 EET
08/30/2008 01:00:00 EET

我很困惑为什么这些时区表现不同,如果它是非洲/开罗时区的错误,或者我误解了时区的运作方式......

对此有任何见解将不胜感激。

1 个答案:

答案 0 :(得分:3)

Cairo time zone更改为夏令时午夜 - 因此跳过了2008年4月25日午夜之间的小时...挂钟开始了:

04/24/2008 23:59:58
04/24/2008 23:59:59
04/25/2008 01:00:00
04/25/2008 01:00:01

尝试在美国东部时区凌晨2点一次添加一天,你会看到同样的事情 - 它会在某个时间点到03:00。

目前尚不清楚你想要达到的目标 - 我倾向于认为最好在特定时区添加“经历的毫秒数”到日期/时间,或者添加“一些逻辑毫秒“到本地日期/时间,不考虑时区。当您在特定区域中从本地时间转换时,您需要考虑模糊性的可能性(一个本地时间发生两次)或跳过(一个本地时间根本没有发生)。

为了增加乐趣,去年萨摩亚完全跳过12月30日,因为时区从-14改为+10 ......

编辑:哦,我的标准建议适用:ditch java.util.Calendar / Date,并使用Joda Time