The java.util.Date toString()
method displays the date in the local time zone.
There are several common scenarios where we want the data to be printed in UTC, including logs, data export and communication with external programs.
java.util.Date
in UTC?toString()
format, which isn't sortable (thanks, @JonSkeet!) with a better format?I think that the standard way of printing the date in a custom format and time zone is quite tedious:
final Date date = new Date();
final String ISO_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS zzz";
final SimpleDateFormat sdf = new SimpleDateFormat(ISO_FORMAT);
final TimeZone utc = TimeZone.getTimeZone("UTC");
sdf.setTimeZone(utc);
System.out.println(sdf.format(date));
I was looking for a one-liner like:
System.out.println(prettyPrint(date, "yyyy-MM-dd'T'HH:mm:ss.SSS zzz", "UTC"));
You asked:
I was looking for a one-liner like:
Ask and ye shall receive. Convert from terrible legacy class Date
to its modern replacement, Instant
.
myJavaUtilDate.toInstant().toString()
2020-05-05T19:46:12.912Z
In Java 8 and later we have the new java.time package built in (Tutorial). Inspired by Joda-Time, defined by JSR 310, and extended by the ThreeTen-Extra project.
The best solution is to sort your date-time objects rather than strings. But if you must work in strings, read on.
An Instant
represents a moment on the timeline, basically in UTC (see class doc for precise details). The toString
implementation uses the DateTimeFormatter.ISO_INSTANT
format by default. This format includes zero, three, six or nine digits digits as needed to display fraction of a second up to nanosecond precision.
String output = Instant.now().toString(); // Example: '2015-12-03T10:15:30.120Z'
If you must interoperate with the old Date
class, convert to/from java.time via new methods added to the old classes. Example: Date::toInstant
.
myJavaUtilDate.toInstant().toString()
You may want to use an alternate formatter if you need a consistent number of digits in the fractional second or if you need no fractional second.
Another route if you want to truncate fractions of a second is to use ZonedDateTime
instead of Instant
, calling its method to change the fraction to zero.
Note that we must specify a time zone for ZonedDateTime
(thus the name). In our case that means UTC. The subclass of ZoneID
, ZoneOffset
, holds a convenient constant for UTC. If we omit the time zone, the JVM’s current default time zone is implicitly applied.
String output = ZonedDateTime.now( ZoneOffset.UTC ).withNano( 0 ).toString(); // Example: 2015-08-27T19:28:58Z
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. Hibernate 5 & JPA 2.2 support java.time.
Where to obtain the java.time classes?
UPDATE: The Joda -Time project is now in maintenance mode, with the team advising migration to the java.time classes.
I was looking for a one-liner
Easy if using the Joda-Time 2.3 library. ISO 8601 is the default formatting.
In the code example below, note that I am specifying a time zone rather than depending on the default time zone. In this case, I'm specifying UTC per your question. The Z
on the end, spoken as "Zulu", means no time zone offset from UTC.
// import org.joda.time.*;
String output = new DateTime( DateTimeZone.UTC );
Output…
2013-12-12T18:29:50.588Z