Search code examples
javadatetimeconsoleformattingdatetimeformatter

Java 8 DateTimeFormatter dropping millis when they're zero?


This seems weird. Java 8 is formatting the output differently depending on whether the millis is zero. How do you force Java 8 (1.8.0_20) to always spit out the millis regardless of if they're zero or not?

public static void main(String[] args) {
    TemporalAccessor zeroedMillis = DateTimeFormatter.ISO_OFFSET_DATE_TIME.parse("2015-07-14T20:50:00.000Z");
    TemporalAccessor hasMillis = DateTimeFormatter.ISO_OFFSET_DATE_TIME.parse("2015-07-14T20:50:00.333Z");
    System.out.println(DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(zeroedMillis));
    System.out.println(DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(hasMillis));
}

2015-07-14T20:50:00Z
2015-07-14T20:50:00.333Z

Solution

  • You don't use ISO_OFFSET_DATE_TIME, basically :)

    If you follow the documentation for that, you end up in the docs of ISO_LOCAL_TIME which has:

    This returns an immutable formatter capable of formatting and parsing the ISO-8601 extended local time format. The format consists of:

    • Two digits for the hour-of-day. This is pre-padded by zero to ensure two digits.
    • A colon
    • Two digits for the minute-of-hour. This is pre-padded by zero to ensure two digits.
    • If the second-of-minute is not available then the format is complete.
    • A colon
    • Two digits for the second-of-minute. This is pre-padded by zero to ensure two digits.
    • If the nano-of-second is zero or not available then the format is complete.
    • A decimal point
    • One to nine digits for the nano-of-second. As many digits will be output as required.

    If you always want exactly 3 digits, I suspect you want DateTimeFormatter.ofPattern with a pattern of yyyy-MM-dd'T'HH:mm:ss.SSSX.