How to get current moment in ISO 8601 format with date, hour, and minute?

Viewed 470978

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);
``
23 Answers

tl;dr

Some of the other Answers are correct in recommending java.time classes but go about using unnecessary lengths for your specific needs.

Instant.now()                               // Capture the current moment in UTC with a resolution as fines nanoseconds but usually in microseconds or milliseconds.
       .truncatedTo( ChronoUnit.MINUTES )   // Lop off any seconds or fractional second, to get a value in whole minutes.
       .toString()                          // Generate a String in standard ISO 8601 format where a `T` separates the year-month-day from the hour-minute-second, and the `Z` on the end for “Zulu” means UTC.

2018-01-23T12:34Z

Instant::toString

The jav.time.Instant class represents a moment in UTC, always in UTC.

Instant instant = Instant.now() ;

instant.toString(): 2018-01-23T12:34:56.123456Z

The Z on the end of your example string 2010-10-12T08:50Z is pronounced “Zulu” and means UTC.

Your desired format happens to comply with the ISO 8601 standard. The java.time classes use these standard formats by default when parsing/generating strings. So no need to specify a formatting pattern. Just call Instant::toString as seen above.

If you specifically want whole minutes without second or fractional second, then truncate. Specify a unit of time via ChronoUnit class.

Instant instant = Instant.now().truncatedTo( ChronoUnit.MINUTES ) ;
String output = instant.toString();  // Generate a `String` object in standard ISO 8601 format.

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?

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.

private static String getCurrentDateIso()
{
    // Returns the current date with the same format as Javascript's new Date().toJSON(), ISO 8601
    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US);
    dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
    return dateFormat.format(new Date());
}
DateTimeFormatter.ISO_DATE_TIME
        .withZone(ZoneOffset.UTC)
        .format(yourDateObject.toInstant())

If you care about performance, I created a library which outperforms standard Java parser and formatter in manipulating with ISO8601-formatted dates. DatetimeProcessor implementations are thread-safe and can be cached in a concurrent map or static fields.

<dependency>
  <groupId>com.axibase</groupId>
  <artifactId>date-processor</artifactId>
  <version>1.0.3</version>
</dependency>
import com.axibase.date.DatetimeProcessor;
import com.axibase.date.PatternResolver;
import org.junit.Before;
import org.junit.Test;

import java.time.Clock;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZoneOffset;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;

public class DateFormatTest {
    private Clock clock;

    @Before
    public void prepare() {
        clock = Clock.fixed(Instant.ofEpochMilli(1571285405300L), ZoneId.of("Europe/Berlin"));
    }

    @Test
    public void testIsoMillis(){
        final DatetimeProcessor formatter = PatternResolver.createNewFormatter("iso");
        assertThat(formatter.print(clock.millis(), ZoneOffset.UTC), is("2019-10-17T04:10:05.300Z"));
    }

    @Test
    public void testIsoMillisLocalZone(){
        final DatetimeProcessor formatter = PatternResolver.createNewFormatter("iso");
        assertThat(formatter.print(clock.millis(), clock.getZone()), is("2019-10-17T06:10:05.300+02:00"));
    }

    @Test
    public void testIsoMinutes(){
        final DatetimeProcessor formatter = PatternResolver.createNewFormatter("yyyy-MM-ddTHH:mmXXX");
        assertThat(formatter.print(clock.millis(), ZoneOffset.UTC), is("2019-10-17T04:10Z"));
    }
}

For those using Joda Time, here's a one-liner in the format yyyy-MM-dd'T'HH:mm:ss'Z'

DateTime(timeInMillis, DateTimeZone.UTC).toString(ISODateTimeFormat.dateTimeNoMillis())
Related