ManoDestra
ManoDestra

Reputation: 6503

Exception when trying to parse a LocalDateTime

I am using the following timestamp format:

yyyyMMddHHmmssSSS

The following method works fine:

public static String formatTimestamp(final Timestamp timestamp, final String format) {
    final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format);
    return timestamp.toLocalDateTime().format(formatter);
}

And, when I pass in a Timestamp with that format string, it returns, for example:

20170925142051591

I then require to map from that string to a Timestamp again, essentially the reverse operation. I know that I can use a SimpleDateFormat and its parse() method, but I'd prefer to stick to java.time style formatting, if possible.

I wrote this (rather hacky) bit of code, which works with some formats, but not with this particular one:

public static Timestamp getTimestamp(final String text, final String format, final boolean includeTime) {
    final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format);
    final TemporalAccessor temporalAccessor = formatter.parse(text);
    if (includeTime) {
        final LocalDateTime localDateTime = LocalDateTime.from(temporalAccessor);
        return DateTimeUtil.getTimestamp(localDateTime);
    } else {
        final LocalDate localDate = LocalDate.from(temporalAccessor);
        return DateTimeUtil.getTimestamp(localDate);
    }
}

It fails on the second line, at the formatter.parse(text); part.

Stack Trace:

java.time.format.DateTimeParseException: Text '20170925142051591' could not be parsed at index 0
    at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949)
    at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)
    at java.time.LocalDateTime.parse(LocalDateTime.java:492)
    at java.time.LocalDateTime.parse(LocalDateTime.java:477)
    at com.csa.core.DateTimeUtil.main(DateTimeUtil.java:169)

Is there a simpler way to achieve what I want without utilising SimpleDateFormat?

Upvotes: 4

Views: 1750

Answers (1)

user7605325
user7605325

Reputation:

It's a bug: https://bugs.openjdk.java.net/browse/JDK-8031085

The link above also provides the workaround: using a java.time.format.DateTimeFormatterBuilder with a java.time.temporal.ChronoField for the milliseconds field:

String text = "20170925142051591";
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
    // date/time
    .appendPattern("yyyyMMddHHmmss")
    // milliseconds
    .appendValue(ChronoField.MILLI_OF_SECOND, 3)
    // create formatter
    .toFormatter();
// now it works
formatter.parse(text);

Unfortunately, there seems to be no way to parse this using only DateTimeFormatter.ofPattern(String).

Upvotes: 5

Related Questions