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?
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.
“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.
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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With