仅1900年Java日期计算中出现30分钟错误

仅1900年Java日期计算中出现30分钟错误,java,time,calendar,Java,Time,Calendar,其结果是: 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.

其结果是:

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());
    }
}

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

这种处理日期的不规则是常见的。请参阅,例如,我正在查找这些故障的实际数据库;将在找到答案时更新答案

这个答案相当不完整,但可能足以让你摆脱困境;我会留下它,但鼓励你接受一个更完整的,如果张贴

Mon Jan 01 00:00:00 KST 1900
Mon Jan 01 23:30:00 KST 1900 // Where is 30 minutes here?
周一1月1日00:00:00中央标准时间1900

-2209017599564

86400000

-2208931199564

星期二1月2日00:05:52 CST 1900

似乎.getTimeInMillis()返回的值与您期望的值不同

getTimeInMillis

公共长getTimeInMillis()

以毫秒为单位返回此日历的时间值

返回:从历元开始的当前时间(UTC毫秒)


这是由于历史GMT偏移量的变化。请参见此处的示例。对于不同的时区,这些变化是不同的。例如,在我的时区(EET)中,您的测试结果不同:

    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());
        System.out.println(cal.getTimeInMillis());
        System.out.println(DAY_MILLIS);
        System.out.println(cal.getTimeInMillis() + DAY_MILLIS);
        cal.setTimeInMillis(cal.getTimeInMillis() + DAY_MILLIS);
        System.out.println(cal.getTime());
    }
因为(根据爪哇语)在1900年1月1日EET的0:20:08时钟被调快了。时区具有确定特定日期的偏移量的方法,TimeZone.getOffset(长日期)API

如果基础时区实现子类支持历史夏令时时间表和GMT偏移量更改,则此方法返回历史上正确的偏移量值

请注意,如果将日历设置为GMT并以GMT打印结果,则不会出现错误

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

    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()));

可能有关系?肯定有关系。同样的基本问题。。。时间是复杂的。我试过这个,我得到了
1月2日星期二00:00:00东部时间1900
。与时区有关吗?我周一1月1日23:39:52 EET 1900对我来说也是正确的。一个更好的问题可能是,您正在运行的Java版本是什么?我在windows上使用1.7.0_21。哇,史诗般有趣的双向飞碟答案。
1900-01-01 00:00:00
1900-01-02 00:00:00