Question

TimeZone utcTimezone_ = TimeZone.getTimeZone("UTC");
TimeZone _utc = TimeZone.getTimeZone("Zulu");
DateFormat _fo = new SimpleDateFormat("yyyy-MM-dd HH:mm");
_fo.setTimeZone(_utc);
GregorianCalendar gc = new GregorianCalendar(_utc);

System.out.println(gc.getTime());
System.out.println(gc.get(GregorianCalendar.MINUTE));
System.out.println(gc.get(GregorianCalendar.HOUR_OF_DAY));

An example of the output when running the above code is:

Mon Sep 16 16:40:37 CST 2013
10
7

In this case I am expecting minutes to be 40 (not 10) and hour to be 16 (not 7). What don't I comprehend about all this at the moment? Thanks.

EDIT: If I change the timezone to CST which is my local timezone the minute and hour still do not match:

TimeZone _utc = TimeZone.getTimeZone("CST");
DateFormat _fo = new SimpleDateFormat("yyyy-MM-dd HH:mm");
_fo.setTimeZone(_utc);
GregorianCalendar gc = new GregorianCalendar(_utc);

System.out.println(gc.getTime());
System.out.println(gc.get(GregorianCalendar.MINUTE));
System.out.println(gc.get(GregorianCalendar.HOUR_OF_DAY));

Output is:

Mon Sep 16 21:23:48 CST 2013
53
6
Was it helpful?

Solution

System.out.println(gc.getTime());

This line prints the calendar in your computer local timezone (getTime() returns a Date containing the number of ms since epoch that is not timezone-related, then the implicit toString() call print it using local timezone). It is CST according to the result.

System.out.println(gc.get(GregorianCalendar.MINUTE));
System.out.println(gc.get(GregorianCalendar.HOUR_OF_DAY));

These lines print the calendar fields in the calendar timezone. It is "Zulu" according to your code.

By the way, it is strongly recommended not to use three-letters timezones:

Three-letter time zone IDs

For compatibility with JDK 1.1.x, some other three-letter time zone IDs (such as "PST", "CTT", "AST") are also supported. However, their use is deprecated because the same abbreviation is often used for multiple time zones (for example, "CST" could be U.S. "Central Standard Time" and "China Standard Time"), and the Java platform can then only recognize one of them.

OTHER TIPS

System.out.println(gc.getTime()); prints Date in local time zone - CST, while you set calendar time zone to GMT.

Avoid legacy date-time classes

GregorianCalendar is one of the terrible date-time classes bundled with the earliest versions of Java. Now supplanted by the java.time classes with the adoption of JSR 310.

ZonedDateTime

Do not waste time trying to understand GregorianCalendar. That class is specifically replaced by ZonedDateTime.

To interoperate with old code not yet updated to java.time, you can convert back-and-forth. Look to new methods added to the old classes.

ZonedDateTime zdt = myGregCal.toZonedDateTime() ;

…and…

GregorianCalendar myGregCal = GregorianCalendar.from( zdt ) ;

Table of date-time types in Java, both modern and legacy

Interrogate for time-of-day

Capture the current moment as seen in a particular time zone.

ZoneId z = ZoneId.of( "America/Chicago" ) ;  // CST is ambiguous, and not a real time zone. Use proper `Continent/Region` names. 
ZonedDateTime zdt = ZonedDateTime.now( z ) ;

Or, let's use your specific example: Mon Sep 16 16:40:37 CST 2013.

LocalDate ld = LocalDate.of( 2013 , Month.SEPTEMBER , 16 ) ;
LocalTime lt = LocalTime.of( 16 , 40 , 37 ) ;

By the pseudo-zone CST, did you mean China Standard Time or Central Standard Time? I will guess the second, so a time zone such as America/Chicago or America/Winnipeg.

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

ZoneId z = ZoneId.of( "America/Chicago" ) ;

Put it all together to determine a moment, a specific point on the timeline.

ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;

zdt.toString(): 2013-09-16T16:40:37-05:00[America/Chicago]

Now we are ready to interrogate for the time-of-day parts as you do in the Question.

int hourZdt = zdt.getHour() ;
int minuteZdt = zdt.getMinute() ;

hourZdt: 16

minuteZdt: 40

To adjust to UTC, extract an Instant object. An Instant is always in UTC, by definition.

Instant instant = zdt.toInstant() ;

instant.toString(): 2013-09-16T21:40:37Z

The Instant class a basic building-block of java.time, with limited features. Let’s convert to an OffsetDateTime for more flexibility. We specify an offset-from-UTC of zero hours-minutes-seconds, for UTC itself, by specifying the constant ZoneOffset.UTC.

OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;

odt.toString(): 2013-09-16T21:40:37Z

Interrogate for time-of-day parts.

int hourOdt = odt.getHour() ;
int minuteOdt = odt.getMinute() ;

hourOdt: 21

minuteOdt: 40

See this code run live at IdeOne.com.


Table of which java.time library to use with which version of Java or Android

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top