How can I get the current date and time in UTC or GMT in Java?
Want to improve this post? Provide detailed answers to this question, including citations and an explanation of why your answer is correct. Answers without enough detail may be edited or deleted.
When I create a new Date object, it is initialized to the current time but in the local timezone. How can I get the current date and time in GMT?
I know these types of topics are completely over discussed, but I found the commons-lang package really handles these common java issues well. commons.apache.org/lang/api-2.5/org/apache/commons/lang/time Check out the various packages they have.
Which local time do you want, and to what precision. Most timezones are defined relative to UTC with a fixed offset measured in SI seconds, but the relationship of GMT which is based on solar observation and a (slightly) variable length second is more complex. The two differ by up to 0.9 seconds.
A Date doesn’t hold a time zone, so «but in the local timezone” is not correct (or inaccurate at best). See All about java.util.Date.
34 Answers 34
tl;dr
Instant.now() // Capture the current moment in UTC.
Generate a String to represent that value:
Details
As the correct answer by Jon Skeet stated, a java.util.Date object has no time zone † . But its toString implementation applies the JVM’s default time zone when generating the String representation of that date-time value. Confusingly to the naïve programmer, a Date seems to have a time zone but does not.
The java.util.Date , j.u.Calendar , and java.text.SimpleDateFormat classes bundled with Java are notoriously troublesome. Avoid them. Instead, use either of these competent date-time libraries:
java.time (Java 8)
Java 8 brings an excellent new java.time.* package to supplant the old java.util.Date/Calendar classes.
Getting current time in UTC/GMT is a simple one-liner…
Instant instant = Instant.now();
That Instant class is the basic building block in java.time, representing a moment on the timeline in UTC with a resolution of nanoseconds.
In Java 8, the current moment is captured with only up to milliseconds resolution. Java 9 brings a fresh implementation of Clock captures the current moment in up to the full nanosecond capability of this class, depending on the ability of your host computer’s clock hardware.
It’s toString method generates a String representation of its value using one specific ISO 8601 format. That format outputs zero, three, six or nine digits digits (milliseconds, microseconds, or nanoseconds) as necessary to represent the fraction-of-second.
If you want more flexible formatting, or other additional features, then apply an offset-from-UTC of zero, for UTC itself ( ZoneOffset.UTC constant) to get a OffsetDateTime .
OffsetDateTime now = OffsetDateTime.now( ZoneOffset.UTC );
System.out.println( "now.toString(): " + now );
now.toString(): 2014-01-21T23:42:03.522Z
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 .
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
- Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later — Part of the standard Java API with a bundled implementation.
- Java 9 adds some minor features and fixes.
- Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
- Later versions of Android bundle implementations of the java.time classes.
- For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
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.
Joda-Time
UPDATE: The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
Using the Joda-Time 3rd-party open-source free-of-cost library, you can get the current date-time in just one line of code.
Joda-Time inspired the new java.time.* classes in Java 8, but has a different architecture. You may use Joda-Time in older versions of Java. Joda-Time continues to work in Java 8 and continues to be actively maintained (as of 2014). However, the Joda-Time team does advise migration to java.time.
System.out.println( "UTC/GMT date-time in ISO 8601 format: " + new org.joda.time.DateTime( org.joda.time.DateTimeZone.UTC ) );
More detailed example code (Joda-Time 2.3)…
org.joda.time.DateTime now = new org.joda.time.DateTime(); // Default time zone. org.joda.time.DateTime zulu = now.toDateTime( org.joda.time.DateTimeZone.UTC );
System.out.println( "Local time in ISO 8601 format: " + now ); System.out.println( "Same moment in UTC (Zulu): " + zulu );
Local time in ISO 8601 format: 2014-01-21T15:34:29.933-08:00 Same moment in UTC (Zulu): 2014-01-21T23:34:29.933Z
For more example code doing time zone work, see my answer to a similar question.
Time Zone
I recommend you always specify a time zone rather than relying implicitly on the JVM’s current default time zone (which can change at any moment!). Such reliance seems to be a common cause of confusion and bugs in date-time work.
When calling now() pass the desired/expected time zone to be assigned. Use the DateTimeZone class.
DateTimeZone zoneMontréal = DateTimeZone.forID( "America/Montreal" ); DateTime now = DateTime.now( zoneMontréal );
That class holds a constant for UTC time zone.
DateTime now = DateTime.now( DateTimeZone.UTC );
If you truly want to use the JVM’s current default time zone, make an explicit call so your code is self-documenting.
DateTimeZone zoneDefault = DateTimeZone.getDefault();
ISO 8601
Read about ISO 8601 formats. Both java.time and Joda-Time use that standard’s sensible formats as their defaults for both parsing and generating strings.
† Actually, java.util.Date does have a time zone, buried deep under layers of source code. For most practical purposes, that time zone is ignored. So, as shorthand, we say java.util.Date has no time zone. Furthermore, that buried time zone is not the one used by Date’s toString method; that method uses the JVM’s current default time zone. All the more reason to avoid this confusing class and stick with Joda-Time and java.time.
How to get this with Pure Java 8 2014-01-21T15:34:29.933-08:00 in the example you used new org.joda.time.DateTime()
@GOXR3PLUS ZonedDateTime.now( ZoneId.of( «America/Los_Angeles» ) ).truncatedTo( ChronoUnit.MILLIS ).toOffsetDateTime().toString() We get the current moment for a specified time zone. Next, lop off any micros/nanos. Then we convert to having only a mere offset-from-UTC (number of hours-minutes-seconds) rather than a full-blown time zone (a history of past, present, and future changes in the offset used by the people of a particular region). Lastly, we generate text representing the value in that OffsetDateTime per the standard ISO 8601 format used by default in its toString method.
@RudraTiwari java.time uses the host OS’ to get the current time. If you cannot trust the local system’s clock, then make a network call to a time server. This topic has been addressed in several existing Questions and Answers on Stack Overflow, so search to learn more.
java.util.Date has no specific time zone, although its value is most commonly thought of in relation to UTC. What makes you think it’s in local time?
To be precise: the value within a java.util.Date is the number of milliseconds since the Unix epoch, which occurred at midnight January 1st 1970, UTC. The same epoch could also be described in other time zones, but the traditional description is in terms of UTC. As it’s a number of milliseconds since a fixed epoch, the value within java.util.Date is the same around the world at any particular instant, regardless of local time zone.
I suspect the problem is that you’re displaying it via an instance of Calendar which uses the local timezone, or possibly using Date.toString() which also uses the local timezone, or a SimpleDateFormat instance, which, by default, also uses local timezone.
If this isn’t the problem, please post some sample code.
I would, however, recommend that you use Joda-Time anyway, which offers a much clearer API.