我正在开发一个应用程序,用于存储一些带有过去时间戳的数据。
我的 JVM 是 IBM Semeru (17),运行于 Europe/Paris tz。但我想将时间戳存储在 UTC (GMT+0)。
下面是我的代码:
<dependencies>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.7.1</version>
</dependency>
</dependencies>
public class Main {
/*
create table theentity (
theid integer not null,
thevalue timestamp(6),
primary key (theid)
)
*/
public static void main(String[] args) {
TimeZone.setDefault( TimeZone.getTimeZone( ZoneId.of( "Europe/Paris" ) ) );
LocalDateTime d_1900_01_01_T_00_09_23 = LocalDateTime.of( 1900, 1, 1, 0, 9, 23, 0 );
LocalDateTime d_1900_01_01_T_00_09_22 = LocalDateTime.of( 1900, 1, 1, 0, 9, 22, 0 );
LocalDateTime d_1900_01_01_T_00_09_21 = LocalDateTime.of( 1900, 1, 1, 0, 9, 21, 0 );
LocalDateTime d_1900_01_01_T_00_09_20 = LocalDateTime.of( 1900, 1, 1, 0, 9, 20, 0 );
LocalDateTime d_1900_01_01_T_00_09_19 = LocalDateTime.of( 1900, 1, 1, 0, 9, 19, 0 );
try(Connection c = DriverManager.getConnection( "jdbc:postgresql://localhost:5432/hibernate_orm_test?preparedStatementCacheQueries=0&escapeSyntaxCallMode=callIfNoReturn",
"postgres", "root")) {
PreparedStatement p = c.prepareStatement( "insert into theentity values(?, ?)" );
bindAndExecute( p, 1, d_1900_01_01_T_00_09_23 );
bindAndExecute( p, 2, d_1900_01_01_T_00_09_22 );
bindAndExecute( p, 3, d_1900_01_01_T_00_09_21 );
bindAndExecute( p, 4, d_1900_01_01_T_00_09_20 );
bindAndExecute( p, 5, d_1900_01_01_T_00_09_19 );
} catch (Exception e) {
e.printStackTrace();
}
}
private static void bindAndExecute(PreparedStatement p, int id, LocalDateTime localDateTime)
throws SQLException {
p.setInt( 1, id );
p.setTimestamp(2,
Timestamp.valueOf( localDateTime ),
Calendar.getInstance( TimeZone.getTimeZone( ZoneId.of( "GMT" ) ) )
);
p.executeUpdate();
}
}
为了排序,我尝试保留 5 个时间戳(请注意,这些时间戳基于欧洲/巴黎,因为TimeZone.setDefault( TimeZone.getTimeZone( ZoneId.of( "Europe/Paris" ) ) );
)
- 1900-01-01T00:09:23
- 1900-01-01T00:09:22
- 1900-01-01T00:09:21
- 1900-01-01T00:09:20
- 1900-01-01T00:09:19
这行代码将把 Europe/Paris tz 翻译为 UTC tz:
p.setTimestamp(2,
Timestamp.valueOf( localDateTime ),
Calendar.getInstance( TimeZone.getTimeZone( ZoneId.of( "GMT" ) ) ) );
执行它将在postresql中创建5行:
theid | thevalue
-------+---------------------
1 | 1900-01-01 00:00:02
2 | 1900-01-01 00:00:01
3 | 1900-01-01 00:00:00
4 | 1899-12-31 23:09:20
5 | 1899-12-31 23:09:19
(5 rows)
你们大多数人可能认为巴黎位于 GMT+1。这是正确的,但实际上并不正确。1900 年,巴黎位于 GMT+00:09:21(9 分 21 秒)!!
因此,前 3 个时间戳已正确保存到表中。但是,奇怪的是在第 4 行。它是,1899-12-31 23:09:20
但我预计它会是1899-12-31 23:59:59
。但似乎在 1899 年,旧的 DateTime API 认为它是 GMT+1。这导致第 4、5 行等等……都是错误的!!
你们能解释一下这个吗?