
在爬公元农历数据,检查数据的时候发现了一件非常有趣的事情,就是在1900年1月1号的时候,当时的timestamp减去86400000ms,发现时间竟然不一致,然后google了一下,发现在stackoverflow上有人提了类似的问题:
http://stackoverflow.com/questions/16409554/30-minute-error-in-java-date-calculation-in-year-1900-only
30 minute error in Java date calculation in year 1900 only
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());
}
}
And it’s result is:
Mon Jan 01 00:00:00 KST 1900
Mon Jan 01 23:30:00 KST 1900 // Where is 30 minutes here?
Most funny and important clue is that this problem happens when year is 1900 only.
Answer:
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
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
This method returns a historically correct offset value if an underlying TimeZone implementation subclass supports historical Daylight Saving Time schedule and GMT offset changes.
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()));
output
1900-01-01 00:00:00
1900-01-02 00:00:00




近期评论