Timestamp can't be parsed Issue java.time.format.DateTimeParseException: Text '9/25/2020, 12:46:00 PM' could not be parsed at index 0 [duplicate]

自古美人都是妖i 提交于 2021-02-02 09:46:05

问题


I am attempting to capture the time before and after I check a timestamp value on a webpage and then confirm my timestamp falls in between those times. However, I'm struggling to convert my String timestamp into a comparable format in a clean way.

        Instant b4 = Instant.now();
                    
        //My code submites a file that then triggers the timestamp. I retrieve it as a string
        //exa string"9/25/2020, 11:03:18 AM"

        DateTimeFormatter dtf = DateTimeFormatter
                .ofPattern("MM/dd/yyyy, HH:mm:ss a")
                .withZone(ZoneId.systemDefault());
        Instant instantTimestamp = Instant.from(dtf.parse(timeStamp));

        Instant after = Instant.now();          

        if (instantTimestamp.isAfter(b4) && instantTimestamp.isBefore(after)) {
            testPass = true;
        }

        Assert.assertTrue(testPass);

My Error: java.time.format.DateTimeParseException: Text '9/25/2020, 12:46:00 PM' could not be parsed at index 0


回答1:


There is a mismatch in the format for the month and its value in the string. The format is MM which specifies two digits but the value is 9 which is a single digit. You can use single letters for month, day, year, hour, minute, seconds etc. to accommodate all allowable number of digits. Also, I suggest you parse it in a case-insensitive way so that upper and lower case (e.g. AM and am) both can be accommodated.

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        // Given date-time string
        String dateTimeString = "9/25/2020, 12:46:00 PM";

        DateTimeFormatter dtf = new  DateTimeFormatterBuilder()
                                    .parseCaseInsensitive()
                                    .appendPattern("M/d/u, H:m:s a")
                                    .toFormatter(Locale.ENGLISH);
                                

        // Convert the given date-time string to LocalDateTime
        LocalDateTime ldt = LocalDateTime.parse(dateTimeString, dtf);
        System.out.println(ldt);
        
        //Convert to LocalDateTime Instant if required
        Instant instant=ldt.toInstant(ZoneOffset.UTC);
        System.out.println(instant);
    }
}

Output:

2020-09-25T12:46
2020-09-25T12:46:00Z



回答2:


The error is due to the format string being used. "MM" requires the month portion of the input string to be exactly two digits long, but "9" is only one digit. In other words, it works for "09/25/2020, 11:03:18 AM", but not for "9/25/2020, 11:03:18 AM".

What's needed here is "M", which doesn't require the value to be preceded by "0":

        DateTimeFormatter dtf = DateTimeFormatter
                .ofPattern("M/dd/yyyy, HH:mm:ss a")
                .withZone(ZoneId.systemDefault());

If the date should also be allowed to be a single digit and not 0-padded for days 0-9, the "M/d/yyyy, HH:mm:ss a" pattern should be used instead.

This is described the DateTimeFormatter Javadocs:

All letters 'A' to 'Z' and 'a' to 'z' are reserved as pattern letters. The following pattern letters are defined:

Symbol  Meaning                     Presentation      Examples
------  -------                     ------------      -------
[...]
 M/L     month-of-year               number/text       7; 07; Jul; July; J
[...]

Text: [...]

Number: If the count of letters is one, then the value is output using the minimum number of digits and without padding. Otherwise, the count of digits is used as the width of the output field, with the value zero-padded as necessary. [...]

Number/Text: If the count of pattern letters is 3 or greater, use the Text rules above. Otherwise use the Number rules above.

Since "M" uses the "number/text" presentation, and the count of its letters your format ("MM") is 2, then it requires exactly two digits for the month. Switching it to a single "M" causes it to use the minimum number of digits (one digit for months 1-9, and two digits for months 10-12).



来源:https://stackoverflow.com/questions/64068677/timestamp-cant-be-parsed-issue-java-time-format-datetimeparseexception-text-9

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!