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年。
答案 0 :(得分:3)
处理日期的这种不正常现象很常见。参见例如Jon Skeet's most famous answer.我正在寻找这些毛刺的实际数据库;会在找到后更新答案。
这个答案相当不完整,但可能足以让你解开;我会离开它,但鼓励你接受一个更完整的,如果发布。
答案 1 :(得分:3)
这是因为历史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
因为(根据Java)时钟在1900年1月1日0:20:08在EET转发。 TimeZone有方法确定特定日期的偏移量,TimeZone.getOffset(长日期)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()));
输出
1900-01-01 00:00:00
1900-01-02 00:00:00
答案 2 :(得分:0)
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());
}
Mon Jan 01 00:00:00 CST 1900
-2209017599564
86400000
-2208931199564
Tue Jan 02 00:05:52 CST 1900
似乎.getTimeInMillis()返回的值与您的预期值不同。
getTimeInMillis
public long getTimeInMillis()
以毫秒为单位返回此Calendar的时间值。
返回:从纪元开始的UTC毫秒的当前时间。