-2

我有一个即时字段,并尝试使用以下方法验证该字段中的值:

Instant.parse("2021-09-29 09:35:07.531")

但是,它会引发错误:

java.time.format.DateTimeParseException:无法在索引 10 处解析文本“2021-09-29 09:35:07.531”。

那么,如何测试Instant字符串格式的给定日期是否为有效Instant日期?

我正在实现导入功能,我需要检查日期单元格。因此,日期通常以即时格式保存在 db 中,因此我需要检查单元格日期值是否是有效的即时日期。所以,如果有更合适的方法,我当然可以按照那个方法。

我不使用该值,我只需要检查日期是否为有效日期。

4

3 回答 3

1

那么,如何测试Instant字符串格式的给定日期是否为有效Instant日期?

它不是。

瞬间是(唯一的)时间点。您的字符串包含日期和时间。在不知道时区的情况下,这可能表示 24 或 27 小时范围内的某个时间点——远非一个时间点。

编辑:我知道您正在从某个地方导入字符串,您无法决定字符串的格式或内容,您需要对其进行验证。您可以将其验证为日期和时间。您基本上无法将其转换为Instant,或者至少您只能在我不知道其有效性的假设下。为了验证,我建议使用此格式化程序:

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

格式化程序重用内置格式化程序并在几秒钟内接受可变数量的小数,我认为这在许多情况下都是有意义的。你更清楚它是否在你的身上。

像这样验证:

    String importedDateTimeString = "2021-09-29 09:35:07.531";
    try {
        LocalDateTime.parse(importedDateTimeString, PARSER);
        System.out.format("Valid date and time: %s%n", importedDateTimeString);
    } catch (DateTimeParseException dtpe) {
        System.out.format("Not a valid date and time: %s. Validation error: %s%n",
                importedDateTimeString, dtpe);
    }

输出:

有效日期和时间:2021-09-29 09:35:07.531

原始建议:因此,请改用包含 UTC 偏移量的格式。特别是用于 UTC 瞬间的 ISO 8601 格式是用于多种用途的推荐选项,例如2021-09-29T01:35:07.531Z.

链接:维基百科文章:ISO 8601

于 2021-10-11T16:18:01.787 回答
1

如果您尝试使用Instant该类,则必须引用时区。所以,让我们试试这个:

LocalDateTime.from(DateTimeFormatter.ofPattern("yyyy-MM-dd H:mm:ss.SSS").parse("2021-09-29 09:35:07.351")).atZone(ZoneId.systemDefault()).toInstant();
于 2021-10-11T14:47:32.123 回答
1

您的日期时间字符串没有时区信息,因此您无法在Instant不引入时区的情况下将其解析为。LocalDateTime如果应该独立于时区使用它,我建议您将其解析为数据库工作并将其用于数据库工作。

演示:

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

public class Main {
    public static void main(String args[]) {
        DateTimeFormatter dtfInput = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SSS", Locale.ENGLISH);
        LocalDateTime ldt = LocalDateTime.parse("2021-09-29 09:35:07.531", dtfInput);
        System.out.println(ldt);
    }
}

输出:

2021-09-29T09:35:07.531

ONLINE DEMO

如何LocalDateTime在 JDBC 中使用?

LocalDateTime下面给出了一个插入a 的示例代码columnfoo(它是TIMESTAMP类型):

PreparedStatement st = conn.prepareStatement("INSERT INTO mytable (columnfoo) VALUES (?)");
st.setObject(1, ldt);
st.executeUpdate();
st.close();

LocalDateTime下面给出了从检索 a 的示例代码columnfoo

Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT * FROM mytable WHERE <some condition>");
while (rs.next()) {
    // Assuming the column index of columnfoo is 1
    LocalDateTime ldt = rs.getObject(1, LocalDateTime.class));
    System.out.println(ldt);
}
rs.close();
st.close();

如果您想将给定的日期时间字符串解析为Instant

如上所述,您需要引入时区才能将其解析为Instant.

演示:

import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String args[]) {
        // Change the ZoneId to the applicable one e.g. ZoneId.of("Etc/UTC")
        DateTimeFormatter dtfInput = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SSS", Locale.ENGLISH)
                                        .withZone(ZoneId.systemDefault());

        Instant instant = Instant.from(dtfInput.parse("2021-09-29 09:35:07.531"));
        System.out.println(instant);
    }
}

我的时区欧洲/伦敦的输出:

2021-09-29T08:35:07.531Z

ONLINE DEMO

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


* 如果您正在为一个 Android 项目工作,并且您的 Android API 级别仍然不符合 Java-8,请通过 desugaring 检查可用的 Java 8+ API。请注意,Android 8.0 Oreo 已经提供java.time.

于 2021-10-11T14:57:52.227 回答