Calendar returns date in wrong time zone

The Answer by Joshi is correct but brief. I’ll expand a bit, and show an alternative with modern classes.

Date has no time zone

Your code calendar.getTime() extracts a java.util.Date object from the java.util.Calendar object.

The java.util.Date class has a well-intentioned but confusing feature where its toString method applies the JVM’s current default time zone while generating the string. This creates the illusion that the Date class has a time zone when it does not. A Date represents a moment on the timeline as a count of milliseconds since the epoch reference date of first moment of 1970 UTC (1970-01-01T00:00:00Z). (Even more confusing, the Date class actually does have a time zone nestled deep inside, but is unreachable and irrelevant to this discussion.)

Avoid legacy date-time classes

The old date-time classes are now legacy, supplanted by the java.time classes. Instead use only the java.time classes.

Instant

For a moment in UTC, the equivalent to java.util.Date, use the Instant class. The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).

Instant instant = Instant.now();  // Current moment in UTC.

ZonedDateTime

To view the same moment through the lens of a particular region’s wall-clock time, apply a ZoneId to get a ZonedDateTime.

Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).

ZoneId z = ZoneId.of( "Asia/Kolkata" );
ZonedDateTime zdt = instant.atZone( z );

Search Stack Overflow for many other Questions and Answers on this topic. This Question is really a duplicate of many others.


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Leave a Comment