插入后一小时后的日期时间。夏令时

Datetime behind an hour after insertion. Daylight savings

我注意到,当我向表中插入某些日期时,我的 MySql 数据库从我的 DateTime 对象中减去了一个小时。示例:

Insert: 2021-03-29 11:44:14.938
Result: 2021-03-29 10:44:14.938

我正在使用 JdbcTemplate.update:

插入 Java.Sql.Timestamp 对象(下面的 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;
    }
});

这仅发生在 DateTime on/after 2021 年 3 月 28 日(这是英国的夏令时)。如果我在 3 月 28 日之前插入,则不会浪费时间。示例:

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 数据库不再自动调整时区。

您可以使用 OffsetDateTime。从 JDBC 4.2 开始,您可以直接将 java.time types 与 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();

Trail: Date Time.

了解现代日期时间 API