Java Instant.parse 无法验证日期
Java Instant.parse cannot validate date
我有一个即时字段并尝试使用以下方法验证该字段中的值:
Instant.parse("2021-09-29 09:35:07.531")
但是,它抛出错误:
java.time.format.DateTimeParseException: Text '2021-09-29
09:35:07.531' could not be parsed at index 10.
那么,我如何测试字符串格式的给定 Instant
日期是否是有效的 Instant
日期?
我正在实施导入功能,我需要检查日期单元格。因此,日期通常以即时格式保存在数据库中,因此我需要检查单元格日期值是否是有效的即时日期。所以,如果有更合适的方法,我当然可以照着做。
我不使用该值,我只需要检查日期是否是有效日期。
如果您尝试使用 Instant
class,则必须参考时区。那么,让我们试试这个:
LocalDateTime.from(DateTimeFormatter.ofPattern("yyyy-MM-dd H:mm:ss.SSS").parse("2021-09-29 09:35:07.351")).atZone(ZoneId.systemDefault()).toInstant();
您的日期时间字符串没有时区信息,因此您无法在不引入时区的情况下将其解析为 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
如何在JDBC中使用LocalDateTime
?
下面给出了将 LocalDateTime
插入 columnfoo
(TIMESTAMP
类型)的示例代码:
PreparedStatement st = conn.prepareStatement("INSERT INTO mytable (columnfoo) VALUES (?)");
st.setObject(1, ldt);
st.executeUpdate();
st.close();
下面给出了从 columnfoo
检索 LocalDateTime
的示例代码:
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);
}
}
在我的时区输出,Europe/London:
2021-09-29T08:35:07.531Z
了解有关 modern Date-Time API* from Trail: Date Time 的更多信息。
* 如果您正在为一个 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查Java 8+ APIs available through desugaring. Note that Android 8.0 Oreo already provides support for java.time
。
So, how can I test if the given Instant
date in String format is a
valid Instant
date?
不是。
瞬间是一个(唯一的)时间点。您的字符串包含一天中的日期和时间。在不知道时区的情况下,这可能表示 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);
}
输出:
Valid date and time: 2021-09-29 09:35:07.531
原始建议:因此请改用包含与 UTC 的偏移量的格式。特别是在 UTC 中的 ISO 8601 格式是出于多种目的的推荐选项,例如 2021-09-29T01:35:07.531Z
.
我有一个即时字段并尝试使用以下方法验证该字段中的值:
Instant.parse("2021-09-29 09:35:07.531")
但是,它抛出错误:
java.time.format.DateTimeParseException: Text '2021-09-29 09:35:07.531' could not be parsed at index 10.
那么,我如何测试字符串格式的给定 Instant
日期是否是有效的 Instant
日期?
我正在实施导入功能,我需要检查日期单元格。因此,日期通常以即时格式保存在数据库中,因此我需要检查单元格日期值是否是有效的即时日期。所以,如果有更合适的方法,我当然可以照着做。
我不使用该值,我只需要检查日期是否是有效日期。
如果您尝试使用 Instant
class,则必须参考时区。那么,让我们试试这个:
LocalDateTime.from(DateTimeFormatter.ofPattern("yyyy-MM-dd H:mm:ss.SSS").parse("2021-09-29 09:35:07.351")).atZone(ZoneId.systemDefault()).toInstant();
您的日期时间字符串没有时区信息,因此您无法在不引入时区的情况下将其解析为 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
如何在JDBC中使用LocalDateTime
?
下面给出了将 LocalDateTime
插入 columnfoo
(TIMESTAMP
类型)的示例代码:
PreparedStatement st = conn.prepareStatement("INSERT INTO mytable (columnfoo) VALUES (?)");
st.setObject(1, ldt);
st.executeUpdate();
st.close();
下面给出了从 columnfoo
检索 LocalDateTime
的示例代码:
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);
}
}
在我的时区输出,Europe/London:
2021-09-29T08:35:07.531Z
了解有关 modern Date-Time API* from Trail: Date Time 的更多信息。
* 如果您正在为一个 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查Java 8+ APIs available through desugaring. Note that Android 8.0 Oreo already provides support for java.time
。
So, how can I test if the given
Instant
date in String format is a validInstant
date?
不是。
瞬间是一个(唯一的)时间点。您的字符串包含一天中的日期和时间。在不知道时区的情况下,这可能表示 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);
}
输出:
Valid date and time: 2021-09-29 09:35:07.531
原始建议:因此请改用包含与 UTC 的偏移量的格式。特别是在 UTC 中的 ISO 8601 格式是出于多种目的的推荐选项,例如 2021-09-29T01:35:07.531Z
.