DST开头/结尾的Java Calendar.roll具有不正确的值

时间:2015-11-20 15:15:12

标签: java calendar timezone

当您尝试翻转DST开始或结束的那一天时,会出现此问题。例如,我们可以将“America / New_York”时区设置为01/11/2015到日历(EDT更改为EST的那一天)并尝试滚动:

TimeZone timeZone = TimeZone.getTimeZone("America/New_York");
Calendar cal = Calendar.getInstance(timeZone);
SimpleDateFormat formatter = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss z");
formatter.setTimeZone(timeZone);
cal.set(Calendar.YEAR, 2015);
cal.set(Calendar.MONTH, 10);
cal.set(Calendar.DAY_OF_MONTH, 1);
for (int i = 0; i < 24; i++)
{
    cal.roll(Calendar.HOUR_OF_DAY, 1);
    System.out.println("Formatted  date: " + formatter.format(cal.getTime()));
}

这是结果:
...
格式化日期:2015.11.01 22:08:32 EST
格式化日期:2015.11.01 23:08:32 EST
格式化日期:2015.11.01 01:08:32 EDT
格式的日期:2015.11.01 01:08:32 EST
格式化日期:2015.11.01 02:08:32 EST
...

1 个答案:

答案 0 :(得分:1)

查看roll javadoc。

  

Calendar上的此默认实现只是反复调用以一个单位滚动的roll()版本。 这可能并不总是做正确的事。

Calendar.roll javadoc

如果您改用Calendar.add并于10月31日开始,您将看到正确的输出 -

Formatted  date: 2015.10.31 21:33:31 EDT
Formatted  date: 2015.10.31 22:33:31 EDT
Formatted  date: 2015.10.31 23:33:31 EDT
Formatted  date: 2015.11.01 00:33:31 EDT
Formatted  date: 2015.11.01 01:33:31 EDT
Formatted  date: 2015.11.01 01:33:31 EST
Formatted  date: 2015.11.01 02:33:31 EST
Formatted  date: 2015.11.01 03:33:31 EST

由于您必须使用roll,因此请添加一些自定义逻辑以确定EST翻转点并相应地进行调整。它有点hackish,但这是一个简单的例子:

    TimeZone timeZone = TimeZone.getTimeZone("America/New_York");
    Calendar cal = Calendar.getInstance(timeZone);
    SimpleDateFormat formatter = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss z");
    formatter.setTimeZone(timeZone);
    cal.set(Calendar.YEAR, 2015);
    cal.set(Calendar.MONTH, 10);
    cal.set(Calendar.DAY_OF_MONTH, 1);
    boolean isPreviousHour23 = (cal.get(Calendar.HOUR_OF_DAY) == 23);
    for (int i = 0; i < 25; i++) {
        cal.roll(Calendar.HOUR_OF_DAY, 1);
        if(isPreviousHour23){
            cal.roll(Calendar.HOUR_OF_DAY, -1);
        }
        isPreviousHour23 = (cal.get(Calendar.HOUR_OF_DAY) == 23);
        System.out.println("Formatted  date: " + formatter.format(cal.getTime()));
    }

给你这个输出:

Formatted  date: 2015.11.01 22:24:13 EST
Formatted  date: 2015.11.01 23:24:13 EST
Formatted  date: 2015.11.01 00:24:13 EDT
Formatted  date: 2015.11.01 01:24:13 EDT
Formatted  date: 2015.11.01 01:24:13 EST
Formatted  date: 2015.11.01 02:24:13 EST
Formatted  date: 2015.11.01 03:24:13 EST
Formatted  date: 2015.11.01 04:24:13 EST