How to get current moment in ISO 8601 format with date, hour, and minute?
What is the most elegant way to get ISO 8601 formatted presentation of the current moment, UTC? It should look like: 2010-10-12T08:50Z
.
Example:
String d = DateFormat.getDateTimeInstance(DateFormat.ISO_8601).format(date);
``
Use SimpleDateFormat
to format any Date
object you want:
TimeZone tz = TimeZone.getTimeZone("UTC");
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'"); // Quoted "Z" to indicate UTC, no timezone offset
df.setTimeZone(tz);
String nowAsISO = df.format(new Date());
Using a new Date()
as shown above will format the current time.
For systems where the default Time Zone is not UTC:
TimeZone tz = TimeZone.getTimeZone("UTC");
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'");
df.setTimeZone(tz);
String nowAsISO = df.format(new Date());
The SimpleDateFormat
instance may be declared as a global constant if needed frequently, but beware that this class is not thread-safe. It must be synchronized if accessed concurrently by multiple threads.
EDIT: I would prefer Joda Time if doing many different Times/Date manipulations...
EDIT2: corrected: setTimeZone
does not accept a String (corrected by Paul)
Java 8 Native
java.time makes it simple since Java 8. And thread safe.
ZonedDateTime.now( ZoneOffset.UTC ).format( DateTimeFormatter.ISO_INSTANT )
Result: 2015-04-14T11:07:36.639Z
You may be tempted to use lighter
Temporal
such asInstant
orLocalDateTime
, but they lacks formatter support or time zone data. OnlyZonedDateTime
works out of the box.
By tuning or chaining the options / operations of ZonedDateTime and DateTimeFormatter, you can easily control the timezone and precision, to a certain degree:
ZonedDateTime.now( ZoneId.of( "Europe/Paris" ) )
.truncatedTo( ChronoUnit.MINUTES )
.format( DateTimeFormatter.ISO_DATE_TIME )
Result: 2015-04-14T11:07:00+01:00[Europe/Paris]
Refined requirements, such as removing the seconds part, must still be served by custom formats or custom post process.
.format( DateTimeFormatter.ISO_LOCAL_DATE_TIME ) // 2015-04-14T11:07:00
.format( DateTimeFormatter.ISO_LOCAL_DATE ) // 2015-04-14
.format( DateTimeFormatter.ISO_LOCAL_TIME ) // 11:07:00
.format( DateTimeFormatter.ofPattern( "yyyy-MM-dd HH:mm" ) ) // 2015-04-14 11:07
For Java 6 & 7, you may consider back-ports of java.time such as ThreeTen-Backport, which also has an Android port. Both are lighter than Joda, and has learned from Joda's experience - esp. considering that java.time is designed by Joda's author.
As of Java 8 you can simply do:
Instant.now().toString();
From the java.time.Instant
docs:
now
public static Instant now()
Obtains the current instant from the system clock.
This will query the system UTC clock to obtain the current instant.
toString
public String toString()
A string representation of this instant using ISO-8601 representation.
The format used is the same as
DateTimeFormatter.ISO_INSTANT
.
Java 8:
thisMoment = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mmX")
.withZone(ZoneOffset.UTC)
.format(Instant.now());
Pre Java 8:
thisMoment = String.format("%tFT%<tRZ",
Calendar.getInstance(TimeZone.getTimeZone("Z")));
From the docs:
'R'
Time formatted for the 24-hour clock as "%tH:%tM"'F'
ISO 8601 complete date formatted as "%tY-%tm-%td".