1

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

        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:文本 '9/25/2020, 12:46:00 PM' 无法在索引 0 处解析

4

2 回答 2

4

该错误是由于使用了格式字符串。“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"则应使用该模式。

DateTimeFormatterJavadocs对此进行了描述:

所有字母“A”到“Z”和“a”到“z”都保留为模式字母。定义了以下模式字母:

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

文字: [...]

数字:如果字母数为 1,则使用最小位数输出值且不进行填充。否则,位数将用作输出字段的宽度,必要时将值补零。[...]

数字/文本:如果模式字母的数量为 3 或更多,请使用上面的文本规则。否则使用上面的数字规则。

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

于 2020-09-25T17:26:28.073 回答
2

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

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 不同,则将其转换为Instant通过ZonedDateTimeeg

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

从Trail: Date Time了解有关现代日期时间 API 的更多信息。

于 2020-09-25T17:25:24.103 回答