5

I am trying to instantiate GregorianCalendar with TimeZone GMT, but whenever I call the getTime() method, it gives me time in local TimeZone. Here is my code:

Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
System.out.println(cal.getTime());

The output I am getting is this:

Sat Nov 28 19:55:49 PKT 2009

Please help!

craftsman
  • 15,133
  • 17
  • 70
  • 86
  • See http://stackoverflow.com/questions/1802758/how-do-i-get-the-current-time-in-a-different-timezone-in-java/1802787#1802787 – b.roth Nov 28 '09 at 16:42

3 Answers3

10

I'm not sure if this answers your question, but this is one way to get "now" in GMT.

import java.text.*
import java.util.* 

Calendar cal = new GregorianCalendar();
Date date = cal.getTime();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy.MM.dd G 'at' HH:mm:ss z");
formatter.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(formatter.format(date));

See the Javadoc on SimpleDateFormat for different patterns. Also, you may want to consider Joda Time as it is far superior for dates and times.

Michael Easter
  • 23,733
  • 7
  • 76
  • 107
  • 1
    +1 for providing a nice detailed example to go with my ramblings, and for suggesting Joda Time. java.util.Date and Calendar are an embarrassment to the Java language. – Carl Smotricz Nov 28 '09 at 15:20
  • Isn't the preferred way of getting a Calendar: Calendar cal = Calendar.getInstance() ? – kgrad Nov 28 '09 at 15:23
  • @kgrad - Calendar is abstract, so you can't do that! – Brian Agnew Nov 28 '09 at 15:28
  • @Brian: You can't directly instantiate an abstract class, but that doesn't stop you from calling its static methods. Still, I wonder how Calendar knows to return a Gregorian instance? The doc doesn't say, so an implementation is free to return a Mayan calendar?? – Carl Smotricz Nov 28 '09 at 16:23
  • How do you get an actual Date instead of a String? – Tulains Córdova May 02 '16 at 19:35
6

The problem is not with GregorianCalendar but with Date, which is being used to format the date/time for toString for println.

If you want control of date formatting, you'll need to instantiate your own DateFormat - I always use SimpleDateFormat because I'm rather picky about how I want my dates to look.

If you're not interested in the details of how the date is formatted, you can also use one of the getInstance... factory methods of DateFormat.

You can explicitly setTimeZone on a DateFormat (including SimpleDateFormat, of course).

Carl Smotricz
  • 66,391
  • 18
  • 125
  • 167
1

tl;dr

Instant.now().toString()

2020-03-08T00:21:48.647951Z

java.util.Date::toString tells a lie

Your call to GregorianCalendar::getTime returns a java.util.Date. As you can see with this method and class naming, these classes are badly designed.

Then you implicitly called Date::toString to generate text that represents the value within that object. That value is actually in UTC, being merely a count of milliseconds since the epoch reference of first moment of 1970 in UTC. Unfortunately, that method dynamically applies the JVM’s current default time zone while generating the text. This creates the illusion of that zone being contained within the object.

Confusing? Yes. One of many reasons to never use these legacy date-time classes. Use java.time classes instead.

java.time

The other Answers are correct, but now obsolete. The terrible Date, Calendar, GregorianCalendar, and SimpleDateFormat classes were years ago supplanted by the modern java.time classes defined in JSR 310.

To get the current moment in UTC, use Instant. This basic building block class in java.time is always in UTC, by definition.

Instant instant = Instant.now() ;

Generate a string in standard in ISO 8601 format by calling toString.

String output = instant.toString() ;

See this code run live at IdeOne.com.

2020-03-08T00:21:48.647951Z

For more flexible formatting when generating strings, use the OffsetDateTime class. Search Stack Overflow to learn about DateTimeFormatter.

OffsetDateTime odt = OffsetDateTime.now( ZoneOffset.UTC ) ;
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154