Home > Enterprise >  DateTimeParseException while parsing date using ZonedDateTime
DateTimeParseException while parsing date using ZonedDateTime

Time:03-15

I have the below program and looks like ZonedDateTime is not able to parse the date string. Should I use a different date format or different library to parse?

import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;

class Scratch {
    public static void main(String[] args) {
        final String inputDate = "2022-03-12T03:59:59 0000Z";
        ZonedDateTime.parse(inputDate, DateTimeFormatter.ISO_DATE_TIME).toEpochSecond();
    }
}

Exception in thread "main" java.time.format.DateTimeParseException: Text '2022-03-12T03:59:59 0000Z' could not be parsed, unparsed text found at index 19 at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2053) at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1952) at java.base/java.time.ZonedDateTime.parse(ZonedDateTime.java:599) at Scratch.main(scratch_29.java:7)

Process finished with exit code 1

CodePudding user response:

That isn't a ISO_DATE_TIME format. That would require something like 2022-03-12T03:59:59 0000 (no 'Z'). A formatter that works looks something like:

import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;


class Scratch {
    public static void main(String[] args) {
        final String inputDate = "2022-03-12T03:59:59 0000Z";

        DateTimeFormatter formatter = new DateTimeFormatterBuilder()
                .parseCaseInsensitive()
                .append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
                .optionalStart()
                .appendPattern(".SSS")
                .optionalEnd()
                .optionalStart()
                .appendZoneOrOffsetId()
                .optionalEnd()
                .optionalStart()
                .appendOffset(" HHMM", "0000")
                .optionalEnd()
                .optionalStart()
                .appendLiteral('Z')
                .optionalEnd()
                .toFormatter();

        long epochSecond = ZonedDateTime.parse(inputDate, formatter).toEpochSecond();

        System.out.println("epochSecond is "   epochSecond);
    }
}

as derived from this post. You can create that formatter in one place and use it over again.

CodePudding user response:

tl;dr

Your input happens to be a screwy variation of the standard IS0 8601 format used by default with the java.time.Instant class. Fix your input string, and parse.

Instant.parse( "2022-03-12T03:59:59 0000Z".replace( " 0000Z" , "Z" ) )

Or, reformatted:

Instant
.parse
( 
    "2022-03-12T03:59:59 0000Z"
    .replace( " 0000Z" , "Z" ) 
)

See this code run live at IdeOne.com.

2022-03-12T03:59:59Z

Details

ZonedDateTime inappropriate here

ZonedDateTime is the wrong class for your input. Your input has a Z which is a standard abbreviation for an offset from UTC of zero hours-minutes-seconds. But no time zone indicated, only a mere offset. So use OffsetDateTime or Instant rather than ZonedDateTime.

0000 and Z redundant

The 0000 also means an offset of zero hours-minutes-seconds. This is the same meaning as the Z. So this part is redundant. I suggest you educate the publisher of your data about the standard ISO 8601 formats. No need to invent formats such as seen in your input.

String manipulation rather than custom formatter

If all your inputs have the same ending of 0000Z, I suggest you clean the incoming data rather than define a formatting pattern.

String input = "2022-03-12T03:59:59 0000Z".replace( " 0000Z" , "Z" ) ;
Instant instant = Instant.parse( input ) ;
  • Related