无法解析时间戳问题 java.time.format.DateTimeParseException:无法在索引 0 处解析文本“9/25/2020,12:46:00 PM”

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

我试图捕捉在我检查网页上的时间戳值之前和之后的时间,然后确认我的时间戳落在这些时间之间。但是,我正在努力以干净的方式将我的字符串时间戳转换为可比较的格式。

        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);

我的错误: java.time.format.DateTimeParseException:无法在索引 0

处解析文本“9/25/2020,12:46:00 PM”

月份的格式与其在字符串中的值不匹配。格式是 MM,它指定了两个数字,但值是 9,它是一个数字。您可以使用单个字母表示月、日、年、小时、分钟、秒等,以容纳所有允许的数字位数。此外,我建议您以 case-insensitive 的方式解析它,以便可以容纳大小写(例如 AMam)。

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);
    }
}

输出:

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

ONLINE DEMO

如果这个Date-Time所属的时区与UTC不同,通过ZonedDateTime将其转换为Instant例如

Instant instant = ldt.atZone(ZoneId.of("America/Los_Angeles")).toInstant();

Trail: Date Time.

了解有关现代 Date-Time API 的更多信息

错误是由于使用了格式字符串。 “MM”要求输入字符串的月份部分正好是两位数,但“9”只是一位数。换句话说,它适用于“09/25/2020,11:03:18 AM”,但不适用于“9/25/2020,11:03:18 AM”。

这里需要的是“M”,不需要值前面加“0”:

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

如果日期也应允许为单个数字且在第 0-9 天不使用 0 填充,则应改用 "M/d/yyyy, HH:mm:ss a" 模式。

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.

由于“M”使用“number/text”表示法,并且您的格式(“MM”)的字母数为 2,因此月份正好需要两位数字。将其切换为单个“M”会导致它使用最少的位数(1-9 个月为一位数,10-12 月为两位数)。