javatimestampjava-timeoffsetdatetimedatetimeparseexception

I have to get OffsetDateTime from a string


String is in this format - "2021-07-13 05:22:18.712"

I tried using this code to parse it. OffsetDateTime parsedDateTime = OffsetDateTime.parse("2021-07-13 05:22:18.712");

But i keep getting this error - org.threeten.bp.format.DateTimeParseException: Text '2021-07-13 05:22:18.712' could not be parsed at index 10.

How do i make it work? Any suggestions will be helpful. Thanks


Solution

  • You need to decide on a time zone (or at least on an offset, but time zone is usually the correct means). And then you need to use a formatter that defines the format that you are trying to parse:

    private static final DateTimeFormatter FORMATTER = new DateTimeFormatterBuilder()
            .append(DateTimeFormatter.ISO_LOCAL_DATE)
            .appendLiteral(' ')
            .append(DateTimeFormatter.ISO_LOCAL_TIME)
            .toFormatter(Locale.ROOT);
    

    With this formatter it’s a pretty simple operation:

        ZoneId zone = ZoneId.of("Asia/Kolkata");
        String input = "2021-07-13 05:22:18.712";
        
        OffsetDateTime dateTime = LocalDateTime.parse(input, FORMATTER)
                .atZone(zone)
                .toOffsetDateTime();
        
        System.out.println(dateTime);
    

    Output from the example snippet is:

    2021-07-13T05:22:18.712+05:30

    Since as @Sweeper noted in a comment your string does not contain UTC offset nor time zone, parse it into a LocalDateTime first. The Local in some java.time class names means without time zone or UTC offset. Then convert into a ZonedDateTime in the intended time zone and further into the desired type, OffsetDateTime.

    If you want to use the default time zone of the JVM, set zone to ZoneId.systemDefault(). Be aware that the default time zone may be changed at any time from another part of your program or another program running in the same JVM, so this is fragile.

    Possible shortcuts

    My formatter is wordy because I wanted to reuse as much as I could from built-in formatters. If you don’t mind building the formatter by hand from a pattern, you may use:

    private static final DateTimeFormatter FORMATTER
            = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SSS", Locale.ROOT);
    

    Or even shorter, you may hand substitute the space in your string with a T to obtain ISO 8601 format and then parse into a LocalDateTime without specifying any formatter at all.

    What went wrong in your code?

    The exception message you got is trying to be helpful:

    But i keep getting this error - org.threeten.bp.format.DateTimeParseException: Text '2021-07-13 05:22:18.712' could not be parsed at index 10.

    Index 10 in your string is where the space between date and time is. The one-arg OffsetDateTime.parse method expects ISO 8601 format, like 2021-07-13T05:22:18.712+05:30, so with a T to denote the start of the time part and with a UTC offset at the end. The absence of the T caused your exception. Had you fixed that, you would have got another exception because of the missing UTC offset.

    Wikipedia article: ISO 8601