Search code examples
java-8tostringlocaltime

Forcing Java 8 LocalTime toString to report omitted values


I have the following datetime helper method that converts a UTC-zoned Java 8 Date into a datetime string:

public static String dateTimeString(Date date) {
    return date.toInstant().atZone(ZoneId.of("UTC")).toLocalDateTime().toString();
}

The desired result is to always have the resultant String be formatted as:

YYYY-MM-dd'T'HH:mm:ss'Z'

Problem is, Java 8 LocalTime#toString() intentionally strips off time components that are zero. So for instance if I have a Date instance that represents June 8, 2018 at 12:35:00 UTC. Then the output of this method above is: 2018-06-08'T'12:35'Z'. Whereas I want it to contain any zeroed-out second/minute/hour components (e.g. 2018-06-08'T'12:35:00'Z').

Any ideas?


Solution

  • private static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssX");
    
    public static String dateTimeString(Date date) {
        return date.toInstant().atOffset(ZoneOffset.UTC).format(formatter);
    }
    

    Just use a fixed format pattern string to get your desired format. Let’s try it:

        System.out.println(dateTimeString(new Date(0)));
        System.out.println(dateTimeString(new Date(1_524_560_255_555L)));
    

    This prints:

    1970-01-01T00:00:00Z
    2018-04-24T08:57:35Z
    
    • In the first example hours, minutes and seconds are printed even if they are 0.
    • In the second example milliseoncds are omitted even when they are non-zero (you see that the milliseconds value I specified ends in 555).

    All of this said, the output conforms to the ISO 8601 format no matter if you have 2018-06-08T12:35Z, 2018-06-08T12:35:00Z or even 2018-06-08T12:35:00.000000000Z. So you may want to check once more whether leaving out the second works for your purpose before you take the trouble of defining your own formatter.

    Link: Wikipedia article: ISO 8601