Java 插入后一小时的日期时间。夏令时
我注意到,当我向表中插入某些日期时,我的MySql数据库从DateTime对象中减去了一个小时。例如:Java 插入后一小时的日期时间。夏令时,java,mysql,spring-boot,datetime,jdbc,Java,Mysql,Spring Boot,Datetime,Jdbc,我注意到,当我向表中插入某些日期时,我的MySql数据库从DateTime对象中减去了一个小时。例如: Insert: 2021-03-29 11:44:14.938 Result: 2021-03-29 10:44:14.938 Insert: 2021-03-26 11:44:14.938 Result: 2021-03-26 11:44:14.938 我正在使用JdbcTemplate.update在下面插入Java.Sql.Timestamp对象时间戳: jdbcTemplate.u
Insert: 2021-03-29 11:44:14.938
Result: 2021-03-29 10:44:14.938
Insert: 2021-03-26 11:44:14.938
Result: 2021-03-26 11:44:14.938
我正在使用JdbcTemplate.update在下面插入Java.Sql.Timestamp对象时间戳:
jdbcTemplate.update(new PreparedStatementCreator() {
@Override
public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
PreparedStatement stmt = con.prepareStatement(
"INSERT INTO Table (date) VALUES (?)");
stmt.setTimestamp(5,timestamp));
return stmt;
}
});
这仅适用于2021年3月28日当天/之后的日期时间,即英国的夏令时。如果我在3月28日之前插入,就不会浪费时间。例如:
Insert: 2021-03-29 11:44:14.938
Result: 2021-03-29 10:44:14.938
Insert: 2021-03-26 11:44:14.938
Result: 2021-03-26 11:44:14.938
我尝试过使用Timestamp而不是DateTime作为MySQL类型,但没有效果
有人知道如何停止这种行为吗?不知道为什么会发生这种情况,但我通过放弃Java.Sql.Timestamp而改用Java.Time.LocalDateTime解决了这个问题 我的插入代码如下所示,其中localDateTime的类型为localDateTime而不是Timestamp:
jdbcTemplate.update(new PreparedStatementCreator() {
@Override
public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
PreparedStatement stmt = con.prepareStatement(
"INSERT INTO Table (date) VALUES (?)");
stmt.setObject(5,localDateTime));
return stmt;
}
});
MySql数据库不再自动调整时区。不确定为什么会发生这种情况,但我通过放弃Java.Sql.Timestamp而改为Java.Time.LocalDateTime解决了这个问题 我的插入代码如下所示,其中localDateTime的类型为localDateTime而不是Timestamp:
jdbcTemplate.update(new PreparedStatementCreator() {
@Override
public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
PreparedStatement stmt = con.prepareStatement(
"INSERT INTO Table (date) VALUES (?)");
stmt.setObject(5,localDateTime));
return stmt;
}
});
MySql数据库不再自动调整时区。您可以使用OffsetDateTime。从JDBC 4.2开始,您可以直接与JDBC一起使用:
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SSS", Locale.ENGLISH);
OffsetDateTime odt = LocalDateTime.parse("2021-03-29 11:44:14.938", dtf)
.atZone(ZoneId.of("Europe/London"))
.toOffsetDateTime();
PreparedStatement st = conn.prepareStatement("INSERT INTO mytable (columnfoo) VALUES (?)");
st.setObject(1, odt);
st.executeUpdate();
st.close();
从了解现代日期时间API。您可以使用OffsetDateTime。从JDBC 4.2开始,您可以直接与JDBC一起使用:
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SSS", Locale.ENGLISH);
OffsetDateTime odt = LocalDateTime.parse("2021-03-29 11:44:14.938", dtf)
.atZone(ZoneId.of("Europe/London"))
.toOffsetDateTime();
PreparedStatement st = conn.prepareStatement("INSERT INTO mytable (columnfoo) VALUES (?)");
st.setObject(1, odt);
st.executeUpdate();
st.close();
从中了解现代日期时间API。您似乎有很多证据表明这是DST问题。您是否尝试过在时区中插入日期/时间?如果您还没有这样做,您可能想阅读:我建议您不要使用时间戳。那门课设计得很糟糕,而且早已过时。相反,将LocalDateTime用于datetime列,或将OffsetDateTime用于timestamp列;两者都来自。您似乎有很多证据表明这是DST问题。您是否尝试过用时区插入日期/时间?如果您还没有这样做,您可能想阅读:我建议您不要使用时间戳。那门课设计得很糟糕,而且早已过时。相反,将LocalDateTime用于datetime列,或将OffsetDateTime用于timestamp列;两个都是我的,谢谢。如果我只是像下面我自己的响应那样,在表的Datetime列中插入一个LocalDateTime对象,会怎么样。它似乎解决了最初的问题,但你说的是OffsetDateTime?对于这个用例,一个比另一个好吗?这取决于MySQL中的数据类型。时间戳列定义一个时间点,需要一个定义时间点的Java对象:OffsetDateTime。datetime列缺少时区或UTC偏移量,因此不定义时间点。这里我更喜欢使用一个也没有偏移量的java对象LocalDateTime。JDBC规范只定义了对带有时区列的时间戳的OffsetDateTime的支持,而不支持没有时区信息的日期/时间。True,@markrotVeel。MySQL尽可能确保时间戳列使用UTC格式,这可能是非标准的。@Ben123-请检查,谢谢。如果我只是像下面我自己的响应那样,在表的Datetime列中插入一个LocalDateTime对象,会怎么样。它似乎解决了最初的问题,但你说的是OffsetDateTime?对于这个用例,一个比另一个好吗?这取决于MySQL中的数据类型。时间戳列定义一个时间点,需要一个定义时间点的Java对象:OffsetDateTime。datetime列缺少时区或UTC偏移量,因此不定义时间点。这里我更喜欢使用一个也没有偏移量的java对象LocalDateTime。JDBC规范只定义了对带有时区列的时间戳的OffsetDateTime的支持,而不支持没有时区信息的日期/时间。True,@markrotVeel。MySQL尽可能确保时间戳列以UTC表示,这可能是非标准的。@Ben123-请检查