将 LocalDateTime 转换为时间戳格式

syv*_*syv 2 java

我将日期时间字符串格式从不同格式转换为时间戳(java.sql)。我已根据不同的格式将其转换为 LocalDateTime。有没有办法将 LocalDateTime 对象转换为时间戳?

Ole*_*.V. 5

它比你想象的更精致,你问的很好。

由于您可以使用 java.time,现代 Java 日期和时间 API,您不应该也希望应用老式且设计不佳的Timestamp类。

我假设您要求 a 是Timestamp因为您需要一些可以存储到 SQL 数据库类型列中的内容timestamp(无时区)。请允许我提及,出于大多数目的,您不想要这样的专栏。标准 SQL 数据类型名不副实timestamp。虽然时间戳的想法是它应该在某事发生时标识一个明确的时间点,但 SQLtimestamp没有定义这样的时间点。它定义了日期和时间,任何人都可以在任何时区自由解释它,允许大约 26 小时的变化。相反,您应该在某个时间点使用timestamp with timezone. 它也没有辜负它的名字,因为它不允许您选择时区。它以 UTC 存储时间,因此可以识别唯一的时间点。

在 Java 端使用 anOffsetDateTime来存储到timestamp with timezone列中。既然你有一个LocalDateTime,你需要转换。对于转换,您需要知道LocalDateTime. 例如:

    final ZoneId zone = ZoneId.of("Asia/Tehran");
    LocalDateTime ldt = LocalDateTime.of(2019, 2, 25, 23, 45);
    OffsetDateTime odt = ldt.atZone(zone).toOffsetDateTime();

    System.out.println("As OffsetDateTime: " + odt);
Run Code Online (Sandbox Code Playgroud)

作为 OffsetDateTime: 2019-02-25T23:45+03:30

存储到您的数据库中:

    PreparedStatement ps = yourDatabaseConnection.prepareStatement(
            "insert into your_table(your_ts_with_timezone) values (?)");
    ps.setObject(1, odt);
    ps.executeUpdate();
Run Code Online (Sandbox Code Playgroud)

如果出于某种原因,您的数据库中确实需要一个没有时区的时间戳,或者您无法更改它,那么您根本不需要任何转换。只需存储LocalDateTime您拥有的:

    PreparedStatement ps = yourDatabaseConnection.prepareStatement(
            "insert into your_table(your_ts_without_timezone) values (?)");
    ps.setObject(1, ldt);
Run Code Online (Sandbox Code Playgroud)

如果您正在对需要老式java.sql.Timestamp对象的遗留 API 进行编程,事情会变得更加微妙。ATimestamp确实定义了一个时间点。因此,您现在需要LocalDateTime从未定义时间点的转换为确实定义时间点的Timestamp,然后将 传递Timestamp给可能将其存储在数据库列中的 API,该列再次未定义明确的时间点。您需要确定用于转换的时区,并且仍然可能存在失败或(更糟糕)给出错误结果的极端情况。但是,正如 the_storyteller 在评论中提到的,转换非常简单:

    Timestamp ts = Timestamp.valueOf(ldt);
    System.out.println("As old-fashioned Timestamp: " + ts);
Run Code Online (Sandbox Code Playgroud)

作为老式时间戳:2019-02-25 23:45:00.0

转换使用 JVM 的默认时区。此设置也由 使用TImestamp.toString(),因此输出符合预期。但是,这是不稳定的,因为在 JVM 中运行的任何程序都可能随时更改默认时区设置,因此通常您不知道会得到什么。要控制用于转换的时区:

    Instant i = ldt.atZone(zone).toInstant();
    Timestamp ts = Timestamp.from(i);
Run Code Online (Sandbox Code Playgroud)

链接