仅在1900年的Java日期计算中出现30分钟错误 [英] 30 minute error in Java date calculation in year 1900 only

查看:580
本文介绍了仅在1900年的Java日期计算中出现30分钟错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

package check;

import java.util.Calendar;

public class Test {
    public static void main(String[] args) {
        // length of a day
        long DAY_MILLIS = 1000 * 60 * 60 * 24;

        Calendar cal = Calendar.getInstance();

        cal.set(1900, 0, 1, 0, 0, 0);
        System.out.println(cal.getTime());

        cal.setTimeInMillis(cal.getTimeInMillis() + DAY_MILLIS);
        System.out.println(cal.getTime());
    }
}

结果是:

Mon Jan 01 00:00:00 KST 1900
Mon Jan 01 23:30:00 KST 1900 // Where is 30 minutes here?

最有趣和重要的线索是,这个问题发生在年仅1900年。

Most funny and important clue is that this problem happens when year is 1900 only.

推荐答案

这是因为历史GMT偏移变化。请参阅此处的示例 http://www.timeanddate.com/worldclock /timezone.html?n=101&syear=1900 。这些更改对于不同的时区是不同的。例如在我的时区(EET),您的测试结果不同:

This is because of historical GMT offset changes. See an example here http://www.timeanddate.com/worldclock/timezone.html?n=101&syear=1900. These changes are different for different time zones. For instance in my time zone (EET) the result of your test is different:

Mon Jan 01 00:00:00 EET 1900
Mon Jan 01 23:39:52 EET 1900

因为(根据Java)时钟被转向0:20:08在1900年1月1日在EET。 TimeZone具有用于确定特定日期的偏移量的方法TimeZone.getOffset(长日期)API

because (according to Java) clocks were turned forward 0:20:08 hours on 1 Jan 1900 in EET. TimeZone has methods to determine offset for a particular date, TimeZone.getOffset(long date) API

此方法返回历史上正确的偏移值,如果基础的TimeZone实现子类支持历史夏令时计划和GMT偏移变化。

This method returns a historically correct offset value if an underlying TimeZone implementation subclass supports historical Daylight Saving Time schedule and GMT offset changes.

请注意,如果将日历设置为GMT并以GMT格式输出结果, 。

Note that if you set Calendar to GMT and print the result in GMT there will be no error.

    SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    df.setTimeZone(TimeZone.getTimeZone("GMT"));
    Calendar cal = Calendar.getInstance();
    cal.setTimeZone(TimeZone.getTimeZone("GMT"));
    cal.set(1900, 0, 1, 0, 0, 0);
    System.out.println(df.format(cal.getTime()));
    cal.setTimeInMillis(cal.getTimeInMillis() + 1000 * 60 * 60 * 24);
    System.out.println(df.format(cal.getTime()));

输出

1900-01-01 00:00:00
1900-01-02 00:00:00

这篇关于仅在1900年的Java日期计算中出现30分钟错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆