我编写了一个 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);
}
在我的默认时区(美国东部)运行时,输出看起来像我预期的那样:
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
我很困惑为什么这些时区的行为不同,是否是非洲/开罗时区的错误,或者我是否误解了时区的工作方式...
任何对此的见解都将不胜感激。
最佳答案
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。
不清楚您要实现的目标是什么 - 我倾向于认为最好是将“经历过的毫秒数”添加到特定时区的日期/时间,或者添加“logical 毫秒”到本地日期/时间,不考虑时区。当您从本地时间转换为特定时区的时间时,您需要考虑出现歧义(一个本地时间出现两次)或跳过(一个本地时间根本不出现)的可能性。
为了增加乐趣,去年萨摩亚完全跳过了 12 月 30 日,因为将时区从 -14 更改为 +10...
编辑:哦,我的标准建议适用:放弃 java.util.Calendar/Date,并使用 Joda Time
关于java - 在 Java 时区添加天数东欧夏令时 (EEST),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9184547/