Michael Howard
Michael Howard

Reputation: 193

How to deal with 'optional' T in ISO-8601 timestamp in Java 8 / JSR 310 / threeten.org ?

In Java 8 time / JSR 310 / threeten.org backport ...

Q: How do I parse ISO-8601 timestamps with either a 'T' or a space ' ' between the date portion and the time portion?

ISO-8601 format for timestamps specifies the literal 'T' to separate the date specification from the time specification:

2015-05-12T15:42:00.123

Many applications generate timestamps in this format with a space ' ' char instead of 'T'. References indicate that ISO-8601 allows this by mutual agreement.

2015-05-12 15:42:00.123

Because I am ingesting data from multiple sources I want to allow either the 'T' or the space ' '.

I observe that the pattern string allows one to specify optional components, but I do not see any way to specify a "choice" in a pattern string ...

Q: Is there any way to make a "choose-exactly-one-of-the-following" in a JSR 310 pattern string?

I was able to get this to work by constructing a DateTimeFormatter with two optional patterns:

DateTimeFormatter dateTimeFormatter = new DateTimeFormatterBuilder()
    .appendOptional(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
    .optionalStart().appendPattern("yyyy-MM-dd HH:mm:ss.SSS").optionalEnd()
    .toFormatter();

Seeing optionalStart() and optionalEnd() led me to:

DateTimeFormatter dateTimeFormatter = new DateTimeFormatterBuilder()
    .appendPattern("[yyyy-MM-dd HH:mm:ss.SSS][yyyy-MM-dd'T'HH:mm:ss.SSS]")
    .toFormatter();

However, I am not confident that this is the correct way to deal with this situation ...

Q: What is the best-practice solution to handle multiple DateTime patterns?

Thanks in advance.

Upvotes: 12

Views: 4611

Answers (1)

Basil Bourque
Basil Bourque

Reputation: 338496

Cleanse Your Input Data

My own practice:

When accepting text from outside my own code, I never trust such external inputs. Heck, I don’t even trust my own internal inputs. I always put such data through a cleaner. As part of that cleaning I replace any SPACE character in any expected ISO 8601 string with a T.

String datetimeInput = input.replace( " ", "T" ) ;

I also make a habit of calling the Google Guava library to trim whitespace from the input string. See this Answer for details.

And check for NULL, non-printing, and other inappropriate characters. Those non-printables make for nasty bugs.

Only after that do I call the date-time libraries ( Joda-Time or java.time ).

Trap Parsing Exception

Also, you should use a try-catch to trap for the parsing exception to more gracefully handle when the date-time input string fails to meet your expectations.

Upvotes: 8

Related Questions