0

Consider the following code snippets.

    TimeZone tz = TimeZone.getTimeZone("GMT");
    System.out.println(tz);

    Calendar cal = Calendar.getInstance();
    cal.set(2017, Calendar.DECEMBER, 25);

    System.out.println("before setting time zone: " + cal.getTime());
    cal.setTimeZone(tz);

    System.out.println("after setting time zone: " + cal.getTime());

Here is the result:

sun.util.calendar.ZoneInfo[id="GMT",offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null]
before setting time zone: Mon Dec 25 22:39:53 EST 2017 
after setting time zone: Mon Dec 25 22:39:53 EST 2017

After the timezone change, why is the printout of the date still showing EST? Shouldn't it be GMT?

kenwood
  • 27
  • 1
  • 5
  • 1
    You set the zone on `cal` and not on `cal.getTime()`. Latter one is just of type `java.util.Date` where you cannot set the zone (and its method `java.util.Date.toString()` only uses the system tz). – Meno Hochschild Dec 16 '17 at 04:58
  • Realizing that `cal.getTime()` gives you a `java.util.Date` this famous blog entry may help: [All about java.util.Date](https://codeblog.jonskeet.uk/2017/04/23/all-about-java-util-date/). – Ole V.V. Dec 16 '17 at 06:44

1 Answers1

7

tl;dr

LocalDate.of( 2017 , Month.DECEMBER , 25 )
         .atStartOfDay( ZoneId.of( "America/New_York" ) )

Avoid legacy date-time classes

You are using terribly troublesome old date-time classes that are now legacy.

To directly answer your Question, the Calendar::getTime method returns a Date. Among the many design flaws in these classes, Date::toString dynamically applies your JVM’s current default time zone while generating a string. Thus your EST appearing.

Never use these classes. Use only their replacement, the industry-leading java.time classes.

java.time

The LocalDate class represents a date-only value without time-of-day and without time zone.

LocalDate xmas2017 = LocalDate.of( 2017 , Month.DECEMBER , 25 ) ;

If you want a date-time, the first moment of the day, you must specify a time zone. A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.

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(!).

Never assume the day starts at 00:00. In some zones, anomalies such as Daylight Saving Time (DST) means the day may start at some other time such as 01:00:00. Let java.time determine the first moment of the day.

Apply a ZoneId to get a ZonedDateTime.

ZoneId z = ZoneId.of( "America/New_York" ) ;
ZonedDateTime zdtNewYork = xmas2017.atStartOfDay( z ) ;

Note that Christmas starts much earlier in India than in New York.

ZonedDateTime zdtKolkta = xmas2017.atStartOfDay( ZoneId.of( "Asia/Kolkata" ) ) ;

This is why the elves’ Logistics department route Santa to Kiribati for his first deliveries. Those islands have the earliest Christmas with a time zone 14 hours ahead of UTC. From there the reindeer fly eastward chasing successive midnights, one after another, as the globe spins into the sunlight of a new day.

If you want that same moment adjusted into UTC, extract a Instant which is always in UTC.

Instant instant = zdt.toInstant() ;

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.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154