David David - 6 months ago 28
Java Question

How to convert ISO8601 format into milliseconds?

I'm pretty surprised that I haven't yet found a really easy way considering how often ISO8601 is used in JSON.

Basically, I'm taking a string that looks like this:

2014-10-23T00:35:14.800Z
and converting it into something like
50 minutes ago
.

First, I have to change
2014-10-23T00:35:14.800Z
to
2014-10-23'T'00:35:14.800Z
, then I need to convert it to milliseconds, then it is easy.

My current code:

private void setTimestamp(String timeCreated) {
int indexOfT = timeCreated.indexOf('T');

String properFormat = new StringBuilder(timeCreated).insert(indexOfT + 1, "'")
.insert(indexOfT, "'")
.toString();

timeStamp = (String) DateUtils.getRelativeTimeSpanString(Long.parseLong(properFormat),
System.currentTimeMillis(),
DateUtils.SECONDS_IN_MILLIS);
}


The culprit is
Long.parseLong(properFormat)
. I need to convert
properFormat
into milliseconds.

Answer

One-Liner In java.time

The java.time framework is built into Java 8 and later. These new classes supplant the old date-time classes bundled with the earliest versions of Java such as java.util.Date/.Calendar. See Tutorial. The java.time classes also supplant the highly successful Joda-Time library, being built by some of the same folks including being led by the same Stephen Colbourne.

An Instant is a moment on the timeline in UTC with a resolution of nanoseconds. You can ask it for a count of milliseconds from its epoch (first moment of 1970 in UTC). But remember that an Instant may have additional data, nanoseconds being finer than milliseconds. So you may be losing data in that tiny fraction of a fraction of a second.

The java.time classes use standard ISO 8601 formats when parsing/generating strings. No need to specify a formatting pattern. The Instant class can directly parse a string.

long millisFromEpoch = Instant.parse( "2014-10-23T00:35:14.800Z" ).toEpochMilli();

To get elapsed time in terms of hours-minutes-seconds, use the Duration class. Feed its between method a pair of moments in time.

Duration duration = Duration.between( Instant.parse( "2014-10-23T00:35:14.800Z" ) , Instant.now() );

One-Liner In Joda-Time

Even easier, with the Joda-Time 2.5 library:

long millisSinceEpoch = new DateTime( "2014-10-23T00:35:14.800Z" ).getMillis();

Joda-Time parses and generates ISO 8601 strings by default. Joda-Time works in Android. The java.util.Date/.Calendar classes are notoriously troublesome, confusing, and flawed. Avoid them.