5

I have a Grails application with the following code:

Date now = Calendar.getInstance().getTime() //Also tried new Date()
println "now: " + now

When I do this, I get now: Thu Aug 18 12:47:09 CDT 2011. I need the date to be in GMT, not local time because I need to store the GMT time in a database. I can use a simpleDateFormat object to print out the time in GMT, but I need to actually store it as GMT.

Question: How do I convert a Date object to a Date object using GMT?

Mike Caputo
  • 1,156
  • 17
  • 33
  • @jpredham should probably get the "answer" to this question as he is correct on retrieving the date/time as GMT. (I tested it myself and found it true.) Plus he's newer and the rest of us already have quite a bit of reputation. – Chris Aldrich Aug 19 '11 at 12:39
  • FYI, the troublesome old date-time classes such as [`java.util.Date`](https://docs.oracle.com/javase/9/docs/api/java/util/Date.html), [`java.util.Calendar`](https://docs.oracle.com/javase/9/docs/api/java/util/Calendar.html), and `java.text.SimpleDateFormat` are now [legacy](https://en.wikipedia.org/wiki/Legacy_system), supplanted by the [java.time](https://docs.oracle.com/javase/9/docs/api/java/time/package-summary.html) classes built into Java 8 & Java 9. See [Tutorial by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Feb 16 '18 at 23:23

8 Answers8

5

This accentuates why Java sucks at time. The previous posts are all close, but we need to be very careful about getting the current time in GMT, and getting the current time in CDT and calling it GMT.

TimeZone reference = TimeZone.getTimeZone("GMT");
Calendar myCal = Calendar.getInstance(reference);

This is the current time in GMT, with a timezone context of GMT.

To convert to a Date object which keeps the zone intact you'll need to call:

TimeZone.setDefault(reference);

This setting will last as long as your current JVM. Now calling get Time should produce the desired result.

myCal.getTime();
jpredham
  • 2,149
  • 1
  • 23
  • 37
  • Kudos to you! I altered my post to better reflect you what said. And even the ZONE_OFFSET thing didn't work. Good catch! – Chris Aldrich Aug 18 '11 at 19:09
2

Well, if you really want time in GMT, you need to get it as GMT (@jpredham is right. Kudos to you! Editing my post to reflect this)

So do the following

//this option uses TimeZone
TimeZone gmtTimeZone = TimeZone.getTimeZone("GMT");
TimeZone.setDefault(gmtTimeZone);
Calendar calendar = Calender.getInstance(gmtTimeZone);

Date myDate = calendar.getTime();
Chris Aldrich
  • 1,904
  • 1
  • 22
  • 37
1

Try this:

println Calendar.getInstance(TimeZone.getTimeZone('GMT')).format('HH:mm:ss')

Note that when you convert to a date, you lose the timezone information. When Java/Groovy formats your Date for printing, it automatically formats it for your local timezone. Don't worry, your date doesn't have a timezone associated with it. You can add the proper timezone back in when you display it like so:

Date now = Calendar.getInstance(TimeZone.getTimeZone('GMT')).time
def formatter = new java.text.SimpleDateFormat('HH:mm:ss')
formatter.timeZone = TimeZone.getTimeZone('GMT')
println formatter.format(now)
ataylor
  • 64,891
  • 24
  • 161
  • 189
0

You are confusing date-time object with its string representation. All common date-time libraries in Java (java.util.Date, Joda-Time, java.time in Java 8) internally track a fractional number of seconds since the first moment of 1970 in UTC while ignoring leap seconds. So in all three libraries, the date-time is internally always in UTC/GMT.

So your question of how to convert a Date object to a Date object in GMT (UTC) makes no sense.

The two better libraries (Joda-Time and java.time) also track a time zone inside the date-time object. The notoriously troublesome java.util.Date has no time zone assigned yet confusingly applies the JVM's current default time zone when it's toString method is invoked.

For the record, Joda-Time makes short work of this.

DateTime nowUtc = DateTime.now( DateTimeZone.UTC );

Calling that object's toString method generates a string in ISO 8601 format in Zulu (UTC) time.

Search StackOverflow for "Joda" and "formatter" to find many examples of adjusting to other time zones.

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

tl;dr

Instant.now()    // Capture current moment in UTC.
    .toString()  // Generate a String object in standard ISO 8601 format, YYYY-MM-DDTHH:MM:SS.SSSSSSSSSZ.

2018-02-16T23:28:01.101324Z

java.time

The modern approach uses java.time classes. Avoid the troublesome legacy date-time classes entirely.

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() ;  // Capture the current moment in UTC.

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

String output = instant.toString() ;

If you need more flexibility than Instant provides, such as formatting while generating strings, use OffsetDateTime with the constant ZoneOffset.UTC.

OffsetDateTime odt = OffsetDateTime.now( ZoneOffset.UTC ) ;  // Capture the current moment in UTC.

To generate strings in non-standard formats, use a DateTimeFormatter.


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.

Using a JDBC driver compliant with JDBC 4.2 or later, you may exchange java.time objects directly with your database. No need for strings nor java.sql.* classes.

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
0

Internally a Calendar object stores the time in UTC (the modern name for GMT). getTimeInMillis() returns a UTC value, and is probably what you want to store.

Jim Garrison
  • 85,615
  • 20
  • 155
  • 190
0

You should try GregorianCalendar#setTimeZone(TimeZone timeZone).

SJuan76
  • 24,532
  • 6
  • 47
  • 87
0

Using System.currentTimeMillis() is not only much faster than using Calendar or Date, it always gives you the GMT time. If you want to display this time, you can use SimpleDateFormat, setting the time zone to what ever you want.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130