我正在使用 jooq (v3.11.9) 访问以 UTC 时间运行的 MySQL 数据库。我使用生成的实体并使用 JSR-310 时间类型。我在配置中使用的选项:
<javaTimeTypes>true</javaTimeTypes>
我的理解是MySQLdatetime
and timestamp
类型都映射到LocalDateTime
这是有道理的,因为 MySQL 不存储时区信息和时间。但是,当我在不同时区的计算机上运行查询时(在我的例子中是东部时间),日期都在我的本地计算机时区中即使会话时区是 UTC.
我已确认会话时区是 UTC
dslContext.fetch("SELECT @@system_time_zone, @@global.time_zone, @@session.time_zone;")
returns
|@@system_time_zone|@@global.time_zone|@@session.time_zone|
+------------------+------------------+-------------------+
|UTC |SYSTEM |SYSTEM |
+------------------+------------------+-------------------+
时区转换示例:
dslContext.select(MY_TABLE.EPOCH_DT_TM, MY_TABLE.CREATION_TIMESTAMP).from(MY_TABLE).limit(1).fetch()
+-----------------------+-----------------------+
|epoch_dt_tm |creation_timestamp |
+-----------------------+-----------------------+
|2019-04-18T13:57:39.163|2019-09-24T16:06:47.754|
+-----------------------+-----------------------+
// CAST to STRING PROPERLY USES SESSION TIMEZONE
dslContext.select(MY_TABLE.EPOCH_DT_TM.cast(org.jooq.impl.SQLDataType.VARCHAR(100)), MY_TABLE.CREATION_TIMESTAMP.cast(org.jooq.impl.SQLDataType.VARCHAR(100))).from(MY_TABLE).limit(1).fetch()
+--------------------------+--------------------------+
|cast |cast |
+--------------------------+--------------------------+
|2019-04-18 17:57:39.163000|2019-09-24 20:06:47.754000|
+--------------------------+--------------------------+
我生成的实体中的字段:
public final TableField<MyTableRecord, LocalDateTime> EPOCH_DT_TM = createField("epoch_dt_tm", org.jooq.impl.SQLDataType.LOCALDATETIME, this, "");
public final TableField<MyTableRecord, LocalDateTime> CREATION_TIMESTAMP = createField("creation_timestamp", org.jooq.impl.SQLDataType.LOCALDATETIME.nullable(false).defaultValue(org.jooq.impl.DSL.field("CURRENT_TIMESTAMP(6)", org.jooq.impl.SQLDataType.LOCALDATETIME)), this, "");
所以我的问题是:
这是预期的行为吗?记录不应该填充表中的原始(非时区)日期吗?由于某种原因,日期是否仍在幕后转换为 java.sql.Timestamp ?
如果这是预期的行为,有什么方法可以确保您获得会话时区中的日期无论客户端计算机上的本地时区如何?如果代码的行为依赖于机器时区,则很难在本地进行测试。
预先感谢您的帮助。