Java Jooq LocalDateTime字段使用系统时区而不是会话时区

Java Jooq LocalDateTime字段使用系统时区而不是会话时区,java,mysql,jooq,jsr310,Java,Mysql,Jooq,Jsr310,我正在使用jooq(v3.11.9)访问在UTC时间运行的MySQL数据库。我已经使用生成的实体,并且正在使用JSR-310时间类型。我在配置中使用的选项: <javaTimeTypes>true</javaTimeTypes> 返回 |@@system_time_zone|@@global.time_zone|@@session.time_zone| +------------------+------------------+-------------------+

我正在使用jooq(v3.11.9)访问在UTC时间运行的MySQL数据库。我已经使用生成的实体,并且正在使用JSR-310时间类型。我在配置中使用的选项:

<javaTimeTypes>true</javaTimeTypes>
返回

|@@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 EPOCH_DT_TM=createField(“EPOCH_DT_TM”,org.jooq.impl.SQLDataType.LOCALDATETIME,this,”);
public final TableField 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

  • 如果这是预期的行为,是否有任何方法可以确保您在会话时区中获取日期,而不考虑客户端计算机上的本地时区?如果代码的行为依赖于机器时区,则很难在本地进行测试


  • 提前感谢您的帮助。

    我最近发现,根据所使用的数据库驱动程序,jOOQ在DateTime解析中可能会表现出一些奇怪的行为

    具体地说,在我的例子中,使用不同的Postgres驱动程序导致DefaultBinding.java接收到一个具有时间戳的日历对象,但调用它的toString来解析。事实证明,toString没有打印时区,然后jOOQ推断它是在当地时间

    对我来说,DefaultBinding.java(我使用了带有时区的时间戳)中有问题的行是:

    由于没有时区,您可能在该系列else ifs中处于不同的位置

    在我的测试中,我还发现更改系统时间会改变结果,但更改会话时间没有任何作用


    幸运的是,改用标准的Postgres驱动程序解决了这个问题。如果没有,我将研究如何重载OffsetDateTime的绑定,以修复toString的使用及其相关时区的剥离。不幸的是,您可能需要走这条路,除非您也在使用SQL驱动程序,而SQL驱动程序是可以升级或替换的。或者,您可以将其与时区一起存储,然后在从数据库加载时转换为所需的时区

    我取消删除了一篇关于这篇文章的后续文章,内容更加详细,这样你就可以查看它了。酷!谢谢你的回答。我将尝试逐步了解这是否是类似的问题。因此,jooq正在TimestampToLocalDateTimeConverter中调用t.toLocalDateTime(),该转换器将时间戳转换为与本地时间中的时间戳相同的时间。我不知道为什么,如果有一个隐式时区(本地JVM时间),为什么不通过创建一个带有本地时区的ZonedDateTime来明确它。你可以继续重载默认绑定来做你想做的事情。我不确定我是否想走这条路,事情已经够复杂了。我只是希望更好地记录jooq中的LocalDateTime被视为本地时区中的日期,而不是没有时区的日期(这就是它应该表示的)。
    else if (type == OffsetDateTime.class) {
        result = (T) offsetDateTime(ctx.resultSet().getString(ctx.index()));
    }