Calendar c = Calendar.getInstance();
System.out.println(c.getTime());
c.set(2007, 0, 1);
System.out.println(c.getTime());
Output:
Tue Sep 12 12:36:24 IST 2017
Mon Jan 01 12:36:24 IST 2007
But, When I use the same code in a different environment, Output changes to below:
Output:
Tue Sep 12 12:36:24 IST 2017
Mon Jan 01 12:36:24 GMT 2007
FYI, I tried to print the timezone of the calendar instance, before and after setting the values and both are in "IST".
I want to know the root cause of this.
The second output in your question is the correct and expected behaviour on a JVM running Irish time (Europe/Dublin). On September 12, 2017 Ireland is on summer time (DST). While it is not clearly documented,
Date.toString()
(which you invoke implicitly when printing theDate
you get fromc.getTime()
) prints the date and time in the JVM’s time zone, which in September is rendered as IST for Irish Summer Time.When you set the date on the
Calendar
object also using Irish time, the hour of day is preserved; in your case you get Jan 01 2007 12:36:24 Irish standard time. Now imagine the confusion if both Irish Summer Time and Irish Standard Time were rendered as IST. You would not be able to distinguish. Instead, since Irish standard time coincides with GMT, this is whatDate.toString()
prints when the date is not in the summer time part of the year (which January isn’t).My guess is that your first output is from a JVM running India time. It too is rendered as IST, and since India doesn’t use summer time, the same abbreviation is given summer and winter.
java.time
Before understanding the explanation for the behaviour you observed, I posted a comment about the outdated and the modern Java date and time classes. I still don’t think the comment is way off, though. This is the modern equivalent of your code:
It prints
If you want to use the JVM’s time zone setting, use
ZoneId.systemDefault()
instead ofZoneId.of("Europe/Dublin")
. As the name states, contrary toDate
,ZonedDateTime
does include a time zone. It corresponds more to the oldCalendar
class. As you can see, itstoString
method prints the offset from UTC (Z
meaning zero offset) and the time zone name in the unambiguous region/city format. I believe that this leaves a lot less room for confusion. If you want to print the date in a specific format, use aDateTimeFormatter
.Appendix: sample output from your code
For the sake of completeness, here are the outputs from your code when running different time zones that may be rendered as IST:
Europe/Dublin (agrees with your second output)
Asia/Tel_Aviv
Asia/Kolkata (agrees with your first output)