FULL PRODUCT VERSION :
Java(TM) SE Runtime Environment 1.7.0_80-b15
ADDITIONAL OS VERSION INFORMATION :
Linux 3.19.0-75-generic #83-Ubuntu SMP Wed Nov 9 23:37:58 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
The following code:
Calendar cal = new GregorianCalendar(2000, 0, 1);
long testCalOne = cal.getTimeInMillis();
cal.setTimeZone(TimeZone.getTimeZone("UTC"));
long testCalTwo = cal.getTimeInMillis();
Calendar cal2 = new GregorianCalendar(2000, 0, 1);
cal2.setTimeZone(TimeZone.getTimeZone("UTC"));
long testCalThree = cal2.getTimeInMillis();
System.out.println(testCalOne + ", " + testCalTwo + ", " + testCalThree);
Prints 946681200000, 946681200000, 946684800000
What is expected is 946684800000, 946684800000, 946684800000
This is done on a machine on a TimeZone GMT +1.
What this means is that getTimeInMillis() is bugged and doesn't return the amount of milliseconds since 1970-01-01 in UTC, but instead in the Calendars timezone. The documentation references it returning it in UTC.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Set timezone to a timezone different from UTC.
Run the following code
Calendar cal = new GregorianCalendar(2000, 0, 1);
long testCalOne = cal.getTimeInMillis();
cal.setTimeZone(TimeZone.getTimeZone("UTC"));
long testCalTwo = cal.getTimeInMillis();
Calendar cal2 = new GregorianCalendar(2000, 0, 1);
cal2.setTimeZone(TimeZone.getTimeZone("UTC"));
long testCalThree = cal2.getTimeInMillis();
System.out.println(testCalOne + ", " + testCalTwo + ", " + testCalThree);
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
946684800000, 946684800000, 946684800000
On the System.out
ACTUAL -
946681200000, 946681200000, 946684800000
On the System.out. This is in a timezone +1 hour relative to UTC.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
Calendar cal = new GregorianCalendar(2000, 0, 1);
long testCalOne = cal.getTimeInMillis();
cal.setTimeZone(TimeZone.getTimeZone("UTC"));
long testCalTwo = cal.getTimeInMillis();
Calendar cal2 = new GregorianCalendar(2000, 0, 1);
cal2.setTimeZone(TimeZone.getTimeZone("UTC"));
long testCalThree = cal2.getTimeInMillis();
System.out.println(testCalOne + ", " + testCalTwo + ", " + testCalThree);
Assert.assertEquals(946684800000L, testCalOne);
Assert.assertEquals(946684800000L, testCalTwo);
Assert.assertEquals(946684800000L, testCalThree);
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Replace
cal.getTimeInMillis()
with
cal.clear(Calendar.ZONE_OFFSET);
cal.setTimeZone(TimeZone.getTimeZone("UTC"));
cal.getTimeInMillis()
Keep in mind this will change cal.
The clear call is necessary because setTimeZone shouldn't affect the getTimeInMillis method, but does due to this bug.
Java(TM) SE Runtime Environment 1.7.0_80-b15
ADDITIONAL OS VERSION INFORMATION :
Linux 3.19.0-75-generic #83-Ubuntu SMP Wed Nov 9 23:37:58 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
The following code:
Calendar cal = new GregorianCalendar(2000, 0, 1);
long testCalOne = cal.getTimeInMillis();
cal.setTimeZone(TimeZone.getTimeZone("UTC"));
long testCalTwo = cal.getTimeInMillis();
Calendar cal2 = new GregorianCalendar(2000, 0, 1);
cal2.setTimeZone(TimeZone.getTimeZone("UTC"));
long testCalThree = cal2.getTimeInMillis();
System.out.println(testCalOne + ", " + testCalTwo + ", " + testCalThree);
Prints 946681200000, 946681200000, 946684800000
What is expected is 946684800000, 946684800000, 946684800000
This is done on a machine on a TimeZone GMT +1.
What this means is that getTimeInMillis() is bugged and doesn't return the amount of milliseconds since 1970-01-01 in UTC, but instead in the Calendars timezone. The documentation references it returning it in UTC.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Set timezone to a timezone different from UTC.
Run the following code
Calendar cal = new GregorianCalendar(2000, 0, 1);
long testCalOne = cal.getTimeInMillis();
cal.setTimeZone(TimeZone.getTimeZone("UTC"));
long testCalTwo = cal.getTimeInMillis();
Calendar cal2 = new GregorianCalendar(2000, 0, 1);
cal2.setTimeZone(TimeZone.getTimeZone("UTC"));
long testCalThree = cal2.getTimeInMillis();
System.out.println(testCalOne + ", " + testCalTwo + ", " + testCalThree);
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
946684800000, 946684800000, 946684800000
On the System.out
ACTUAL -
946681200000, 946681200000, 946684800000
On the System.out. This is in a timezone +1 hour relative to UTC.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
Calendar cal = new GregorianCalendar(2000, 0, 1);
long testCalOne = cal.getTimeInMillis();
cal.setTimeZone(TimeZone.getTimeZone("UTC"));
long testCalTwo = cal.getTimeInMillis();
Calendar cal2 = new GregorianCalendar(2000, 0, 1);
cal2.setTimeZone(TimeZone.getTimeZone("UTC"));
long testCalThree = cal2.getTimeInMillis();
System.out.println(testCalOne + ", " + testCalTwo + ", " + testCalThree);
Assert.assertEquals(946684800000L, testCalOne);
Assert.assertEquals(946684800000L, testCalTwo);
Assert.assertEquals(946684800000L, testCalThree);
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Replace
cal.getTimeInMillis()
with
cal.clear(Calendar.ZONE_OFFSET);
cal.setTimeZone(TimeZone.getTimeZone("UTC"));
cal.getTimeInMillis()
Keep in mind this will change cal.
The clear call is necessary because setTimeZone shouldn't affect the getTimeInMillis method, but does due to this bug.