Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Java Date() returns date in UTC" - what does it actually mean?

Tags:

java

date

gmt

My question might be trivial but I'm just looking for clarifications. I read somewhere in SO that Java's Date() is actually always in UTC time, how come when I create a Date() object and print it using toString(), it displays the local time. If this is not the right way to print it, what should it be so I would get the UTC time?

like image 775
jasonline Avatar asked May 10 '11 08:05

jasonline


2 Answers

For formatting, you should really use a DateFormat implementation (e.g. SimpleDateFormat). That will let you specify the time zone (and output format). Date itself has no concept of time zones - it represents an instant in time, using the "milliseconds since the Unix epoch" as storage. The toString() method just converts whatever instant is represented into a local time using the system default time zone.

Personally I'd advise moving away from the built-in date/time API entirely and using Joda Time as a far more sensible library.

like image 154
Jon Skeet Avatar answered Sep 24 '22 21:09

Jon Skeet


“Java Date() returns date in UTC” - what does it actually mean?

UTC is the baseline against which we adjust the time-of-day around the globe.

Since the caveman days, noon, or 12:00, is when the sun is directly overhead. Of course, that means different moments in different places. Noon in Japan happens hours earlier than in Europe, and noon arrives even later in the Americas.

In the modern era, humans created time zones where noon would apply to a wide swath of land, so wide that the sun may not be overhead simultaneously across all of it. So the sun, or “solar time”, could no longer be used to define time. The modern time zone is defined as being a certain number of hours-minutes-seconds from the baseline.

What baseline? That baseline was arbitrarily chosen by the fate of history to be the latitude that runs through the Royal Observatory, Greenwich in London, England, UK. Time zones to the east are a certain number of hours-minutes-seconds ahead of UTC, and to the west a certain number behind UTC. For example, India is five and half hours ahead of UTC, and Martinique in the Caribbean is four hours behind UTC.

If the offset is zero hours-minutes-seconds, then we say we are “at UTC” or “in UTC”.

Java's Date() is actually always in UTC time

Yes, the java.util.Date class, despite its unfortunate name, represents a date with time-of-day with an offset-from-UTC of zero.

The Date class is now obsolete, by the way. The java.time.Instant class is now used as its replacement to represent a moment in UTC. Instant has a resolution of nanoseconds, finer than the milliseconds of Date.

when I create a Date() object and print it using toString(), it displays the local time

There are many problems with the legacy date-time classes. One is the poor naming, as mentioned above. Another is the well-intentioned by unfortunate design decision made that Date::toString should dynamically apply the JVM’s current default time zone to adjust from UTC while generating the text. This bad decision has caused no end of confusion and pain to Java programmers, as it creates the illusion that java.util.Date has a time zone assigned.

As an aside… Even worse, the java.util.Date does have a time zone, but buried deep in its source code with no accessor getter/setter methods. But that zone does affect some behavior such as determining equality between objects of this class. Confusing? Yes. As I said, these legacy date-time classes are riddled with poor design decisions.

If this is not the right way to print it, what should it be so I would get the UTC time?

The right way is to avoid the Date class entirely. Use only the java.time classes instead.

➥ To get the current moment in UTC, use Instant.now.

Instant instant = Instant.now() ;

Tip: If you want to alter the time for the purpose of artificial testing, pass an alternate Clock to Instant.now( Clock ).

To generate a String with text representing the value of that Instant in standard ISO 8601 format, simply call toString. Fortunately this class does not inject a time zone like Date does. The Instant::toString method tells the simple truth, text of the moment in UTC.

String output = instant.toString() ;

2019-12-03T10:15:30.032163Z

Be clear that date-time objects such as Instant do not have a “format”. Only text representing the value of those objects have a format. The text and the date-time object are distinct and separate from each other. A date-time object can generate such text, and can parse such text, but is not actually the text.

If you need flexibility in generating text in other formats, apply a ZoneOffset to get a OffsetDateTime object, or apply a ZoneId to get a a ZonedDateTime object. Apply a DateTimeFormatter object to generate the text.


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.

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.
  • Java SE 6 and Java SE 7
    • Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
  • Android
    • 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.

like image 31
Basil Bourque Avatar answered Sep 23 '22 21:09

Basil Bourque