应用 DST 更改时 add() 的 java.util.GregorianCalendar 问题

标签 java date calendar

我的要求是根据日程安排的频率确定下一个日期。 因此,如果频率为每日且第一个日期为 25-Oct-2015 23:59:59, 下一个预产期应该正好相隔 24 小时,即 2015 年 10 月 26 日 23:59:59

Calendar.add(int field, int amount) 似乎正在处理相同的问题 例如:

每日频率 -- calendar.add(Calendar.DATE, 1);

每周频率 -- calendar.add(Calendar.DATE, 7);

每月频率 -- calendar.add(Calendar.MONTH, 1);

以下是其代码摘要:

public static void main(String[] args) {
        Calendar calendar = new GregorianCalendar();

        for(int i=0;i<10;i++) {
            calendar.add(Calendar.DATE, 1);
            System.out.println(calendar.getTime());
        }
    }

==================================================

Thu Oct 29 17:17:26 IST 2015 -- in all cases diff is 24 hrs
Fri Oct 30 17:17:26 IST 2015
Sat Oct 31 17:17:26 IST 2015
Sun Nov 01 17:17:26 IST 2015
Mon Nov 02 17:17:26 IST 2015
Tue Nov 03 17:17:26 IST 2015
Wed Nov 04 17:17:26 IST 2015
Thu Nov 05 17:17:26 IST 2015
Fri Nov 06 17:17:26 IST 2015

如果频率为每日且服务器位于东部时间 (EDT),则 add() 会发生一些异常

自 11 月 1 日起,夏令时设置的更改同样会反射(reflect)在添加中

public static void main(String[] args) {
        Calendar calendar = new GregorianCalendar();        
        calendar.setTimeZone(TimeZone.getTimeZone("US/Eastern"));

        for(int i=0;i<10;i++) {
            calendar.add(Calendar.DATE, 1);
            System.out.println(calendar.getTime());
        }
    }

-------------------------------------

Wed Oct 28 17:18:14 IST 2015
Thu Oct 29 17:18:14 IST 2015
Fri Oct 30 17:18:14 IST 2015
Sat Oct 31 17:18:14 IST 2015
Sun Nov 01 18:18:14 IST 2015 -- here diff is of 24 + 1 hr
Mon Nov 02 18:18:14 IST 2015
Tue Nov 03 18:18:14 IST 2015
Wed Nov 04 18:18:14 IST 2015 -- else everywhere diff is 24 hours
Thu Nov 05 18:18:14 IST 2015
Fri Nov 06 18:18:14 IST 2015

如果第一个日期是 2015 年 10 月 25 日 23:59:59,在这种情况下,额外的 1 小时轮类会导致异常,如下所示 2015 年 10 月 31 日 23:59:59, 下一个日期是 2-11-2015 00:59:59

进一步观察代码,发现

// The rest of the fields (week, day or AM_PM fields)
// require time zone offset (both GMT and DST) change
// adjustment.

实际上服务器位于 EDT,我正在那里获取以下 I/O 关系。 我只是尝试在 IST 中的本地实例上调试它。

    public static void main(String[] args) {
        Calendar calendar = new GregorianCalendar();

        for(int i=0;i<10;i++) {
            calendar.add(Calendar.DATE, 1);
            System.out.println(calendar.getTime());
        }
    }


Wed Oct 28 08:09:48 EDT 2015
Thu Oct 29 08:09:48 EDT 2015
Fri Oct 30 08:09:48 EDT 2015
Sat Oct 31 08:09:48 EDT 2015
Sun Nov 01 08:09:48 EST 2015
Mon Nov 02 08:09:48 EST 2015
Tue Nov 03 08:09:48 EST 2015
Wed Nov 04 08:09:48 EST 2015
Thu Nov 05 08:09:48 EST 2015
Fri Nov 06 08:09:48 EST 2015

使用库来确保生成的日期顺序正确的可靠方法应该是什么。

最佳答案

尝试下面的代码。下面的代码并不是简单地将 1 加到 DAY 或 MONTH 上。为了获得正确的结果,它增加了一天的毫秒数。

    public static void main(String[] args) {
    DateFormat formatter = new SimpleDateFormat("EEE MMM dd hh:mm:ss z yyyy");
    Calendar calendar = Calendar.getInstance();
    formatter.setTimeZone(TimeZone.getTimeZone("US/Eastern"));
    calendar.setTimeInMillis(System.currentTimeMillis());
    long time = calendar.getTimeInMillis();
    for(int i=0;i<10;i++) {
        System.out.println(formatter.format(calendar.getTime()));
        time = time + 86400000; 
        calendar.setTimeInMillis(time);
    }
}

确实可以通过更改行来更改日期格式 -

new SimpleDateFormat("E MMM dd hh:mm:ss z yyyy");

它给出输出 -

2015 年 10 月 27 日 08:15:59 美国东部时间
2015 年 10 月 28 日 08:15:59 美国东部时间
2015 年 10 月 29 日 08:15:59 美国东部时间
2015 年 10 月 30 日 08:15:59 美国东部时间
2015 年 10 月 31 日 08:15:59 美国东部时间
2015 年 11 月 1 日 07:15:59 美国东部时间
美国东部时间 2015 年 11 月 2 日 07:15:59
2015 年 11 月 3 日 07:15:59 美国东部时间
2015 年 11 月 4 日 07:15:59 美国东部时间
2015 年 11 月 5 日 07:15:59 美国东部时间

关于应用 DST 更改时 add() 的 java.util.GregorianCalendar 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33367326/

相关文章:

java - 将音乐添加到 LibGDX 不起作用。收到错误消息,指出 newMusic 不是方法 最近还有其他人遇到此问题吗?

javascript - 在 javascript 或 momentjs 中获取给定的日期格式(指定格式的字符串)

jquery - 单击链接打开日期选择器

php mysql 和嵌套循环

java - 尝试创建进度条

java - hibernate.cfg.xml 在项目中的位置?

java - 使用流在 Java 中映射映射值

java - 如何在 Java 中仅从月份和年份生成日期?

c# - npgsql中的日期类型是什么?

java - 为什么 Java 日历报告的日期不正确?