Search code examples
javajava-8date-formattingdateformatter

Handling multiple formats in DateTimeFormatter


I am developing using Java 8 a function that must handle the conversion from String to LocalDateTime of the following dates:

  • 2019-06-20 12:18:07.207 +0000 UTC
  • 2019-06-20 12:18:07.20 +0000 UTC
  • 2019-06-20 12:18:07.2 +0000 UTC
  • 2019-06-20 12:18:07 +0000 UTC

The strings are produced from an external library that I cannot change.

Following the suggestions given in the SO answer Optional parts in SimpleDateFormat, I tried using the optional formatting offered by the type DateTimeFormatter, using the characters [ and ]. I tried the following patterns:

  • yyyy-MM-dd HH:mm:ss[.S[S[S]]] Z z
  • yyyy-MM-dd HH:mm:ss[.S[S][S]] Z z

However, neither of them works.

Any suggestion?


Solution

  • You can build the pattern using DateTimeFormatterBuilder and reuse ISO_LOCAL_DATE and ISO_LOCAL_TIME constants:

        DateTimeFormatter formatter = new DateTimeFormatterBuilder()
                .append(DateTimeFormatter.ISO_LOCAL_DATE)
                .appendLiteral(" ")
                .append(DateTimeFormatter.ISO_LOCAL_TIME)
                .appendPattern("[ Z z]")
                .toFormatter();
    
        ZonedDateTime dt = ZonedDateTime.parse(date, formatter);
    

    The trick is that DateTimeFormatter.ISO_LOCAL_TIME handles the different number of digit used to represent milliseconds its own. From DateTimeFormatter.ISO_LOCAL_TIME JavaDoc:

    This returns an immutable formatter capable of formatting and parsing the ISO-8601 extended local time format. The format consists of:
    [..]
    One to nine digits for the nano-of-second. As many digits will be output as required.