I'm using jooq (v3.11.9) to access a MySQL database that is running in UTC time. I've using generated entities and am using JSR-310 time types. The option I'm using in my config:
<javaTimeTypes>true</javaTimeTypes>
My understanding is that the MySQLdatetime
and timestamp
types both map to LocalDateTime
which makes sense as MySQL doesn't store timezone information with the times. However when I run queries on a machine in a different timezone (in my case EST) the dates are all in my local machine timezone even though the session timezone is UTC.
I've confirmed that the session timezone is 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 |
+------------------+------------------+-------------------+
Example of timezone conversion:
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|
+--------------------------+--------------------------+
The fields in my generated entities:
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, "");
So my questions are:
Is this expected behavior? Shouldn't the record get populated with the raw (non timezoned) date in the table. Are the dates still getting converted to java.sql.Timestamp under the hood for some reason?
If this is expected behavior is there any way to ensure that you get dates in the session timezone regardless of the local timezone on the client machine? It is very hard to test locally if the behavior of the code is dependent on the machine timezone.
Thank you in advance for your help.