How do I format a javax.time.Instant as a string in the local time zone?

Derek Mahar picture Derek Mahar · Dec 6, 2012 · Viewed 21.8k times · Source

How do I format a javax.time.Instant as a string in the local time zone? The following translates a local Instant to UTC, not to the local time zone as I was expecting. Removing the call to toLocalDateTime() does the same. How can I get the local time instead?

public String getDateTimeString( final Instant instant )
{
    checkNotNull( instant );
    DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder();
    DateTimeFormatter formatter = builder.appendPattern( "yyyyMMddHHmmss" ).toFormatter();
    return formatter.print( ZonedDateTime.ofInstant( instant, TimeZone.UTC ).toLocalDateTime() );
}

Note: We're using the older version 0.6.3 of the JSR-310 reference implementation.

Answer

JodaStephen picture JodaStephen · Apr 9, 2013

Answering this question wrt the nearly finished JDK1.8 version

DateTimeFormatter formatter =
  DateTimeFormatter.ofPattern("yyyyMMddHHmmss").withZone(ZoneId.systemDefault());
return formatter.format(instant);

The key is that Instant does not have any time-zone information. Thus it cannot be formatted using any pattens based on date/time fields, such as "yyyyMMddHHmmss". By specifying the zone in the DateTimeFormatter, the instant is converted to the specified time-zone during formatting, allowing it to be correctly output.

An alternative approach is to convert to ZonedDateTime:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
return formatter.format(ZonedDateTime.ofInstant(instant, ZoneId.systemDefault()));

Both approaches are equivalent, however I would generally choose the first if my data object was an Instant.