jee*_*yul 9 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.set(1900, 0, 1, 0, 0, 0);
System.out.println(cal.getTime());
cal.setTimeInMillis(cal.getTimeInMillis() + DAY_MILLIS);
System.out.println(cal.getTime());
}
}
Run Code Online (Sandbox Code Playgroud)
它的结果是:
Mon Jan 01 00:00:00 KST 1900
Mon Jan 01 23:30:00 KST 1900 // Where is 30 minutes here?
Run Code Online (Sandbox Code Playgroud)
最有趣和最重要的线索是这个问题发生在年仅1900年.
这是因为历史 GMT 偏移量发生了变化。请参阅此处的示例http://www.timeanddate.com/worldclock/timezone.html?n=101&syear=1900。这些变化对于不同的时区是不同的。例如,在我的时区(EET),您的测试结果是不同的:
Mon Jan 01 00:00:00 EET 1900
Mon Jan 01 23:39:52 EET 1900
Run Code Online (Sandbox Code Playgroud)
因为(根据 Java)时钟在 EET 的 1900 年 1 月 1 日向前调了 0:20:08 小时。TimeZone 有方法确定特定日期的偏移量,TimeZone.getOffset(long date) API
如果底层 TimeZone 实现子类支持历史夏令时计划和 GMT 偏移更改,则此方法返回历史正确的偏移值。
请注意,如果将日历设置为 GMT 并以 GMT 打印结果,则不会出现错误。
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()));
Run Code Online (Sandbox Code Playgroud)
输出
1900-01-01 00:00:00
1900-01-02 00:00:00
Run Code Online (Sandbox Code Playgroud)