JOOQ 日期,忽略时区
JOOQ date as is, ignore timezone
我从 SQL 的日期列中得到 2019-09-01
,但在使用 Jooq 前 1 天。我认为这是因为我的应用程序(OS 级别和 Java 前端)使用 US/Eastern
,但数据库使用 UTC。请参阅下面的 SQL:
select kpisd1, convert_tz( kpisd1, 'US/Eastern', @@session.time_zone), convert_tz( kpisd1, @@session.time_zone, 'US/Eastern' ), @@session.time_zone from kpi where kpiprc = '00006330263815' and kpikpi = 'TURN' and kpists = 'HIST';
+---------------------+--------------------------------------------------------+---------------------------------------------------------+---------------------+
| kpisd1 | convert_tz( kpisd1, 'US/Eastern', @@session.time_zone) | convert_tz( kpisd1, @@session.time_zone, 'US/Eastern' ) | @@session.time_zone |
+---------------------+--------------------------------------------------------+---------------------------------------------------------+---------------------+
| 2019-09-01 00:00:00 | 2019-09-01 04:00:00 | 2019-08-31 20:00:00 | UTC |
+---------------------+--------------------------------------------------------+---------------------------------------------------------+---------------------+
1 row in set (0.00 sec)
实际上,我的 C 程序正在更新数据库,在将其添加到数据库之前并没有真正进行任何时区转换。它根据 OS 时区获取日期,然后使用该日期。因此,如果它添加 9/1/2019,我预计会在 9/1/2019 返回。我试过 select date( kpisd1 )
,但也没有用。即使我打印出原始 java.sql.Date,它也不匹配 DB,这意味着它可能在 JDBC 内部被转换,我猜。有什么想法吗?
我唯一的其他选择是将数据库时区从 UTC 转换为 "US/Eastern"(以匹配我的应用程序服务器上的时区),但我需要研究其后果,所以我尽量不这样做急着走这么猛的一步(这是生产环境)。
根据@knutwannheden 的建议,我更改了:
databaseUrl = "jdbc:mysql://" + host.trim() + ":3306/" + db.trim();
至
Calendar now = Calendar.getInstance();
databaseUrl = "jdbc:mysql://" + host.trim() + ":3306/" + db.trim() +
"?serverTimezone=" + now.getTimeZone().getID();
我根据上面引用的文档选择了serverTimezone
:
serverTimezone
Override detection/mapping of time zone. Used when time zone from
server doesn't map to Java time zone
Since version: 3.0.2
是的,在我的情况下这实际上不是真的 - 我的 MySql 服务器设置为 UTC,它确实映射到客户端,但是因为我不希望它映射,所以我尝试了这个并且它有效.我没有尝试其他时区参数,因为这个参数立即起作用,但是 noTimezoneConversionForDateType
或其他时区参数之一很有可能起作用。
如果有人对此解决方案有疑虑,请提出来。我想我有点作弊,但我现在想不出任何真正危险的副作用。
我从 SQL 的日期列中得到 2019-09-01
,但在使用 Jooq 前 1 天。我认为这是因为我的应用程序(OS 级别和 Java 前端)使用 US/Eastern
,但数据库使用 UTC。请参阅下面的 SQL:
select kpisd1, convert_tz( kpisd1, 'US/Eastern', @@session.time_zone), convert_tz( kpisd1, @@session.time_zone, 'US/Eastern' ), @@session.time_zone from kpi where kpiprc = '00006330263815' and kpikpi = 'TURN' and kpists = 'HIST';
+---------------------+--------------------------------------------------------+---------------------------------------------------------+---------------------+
| kpisd1 | convert_tz( kpisd1, 'US/Eastern', @@session.time_zone) | convert_tz( kpisd1, @@session.time_zone, 'US/Eastern' ) | @@session.time_zone |
+---------------------+--------------------------------------------------------+---------------------------------------------------------+---------------------+
| 2019-09-01 00:00:00 | 2019-09-01 04:00:00 | 2019-08-31 20:00:00 | UTC |
+---------------------+--------------------------------------------------------+---------------------------------------------------------+---------------------+
1 row in set (0.00 sec)
实际上,我的 C 程序正在更新数据库,在将其添加到数据库之前并没有真正进行任何时区转换。它根据 OS 时区获取日期,然后使用该日期。因此,如果它添加 9/1/2019,我预计会在 9/1/2019 返回。我试过 select date( kpisd1 )
,但也没有用。即使我打印出原始 java.sql.Date,它也不匹配 DB,这意味着它可能在 JDBC 内部被转换,我猜。有什么想法吗?
我唯一的其他选择是将数据库时区从 UTC 转换为 "US/Eastern"(以匹配我的应用程序服务器上的时区),但我需要研究其后果,所以我尽量不这样做急着走这么猛的一步(这是生产环境)。
根据@knutwannheden 的建议,我更改了:
databaseUrl = "jdbc:mysql://" + host.trim() + ":3306/" + db.trim();
至
Calendar now = Calendar.getInstance();
databaseUrl = "jdbc:mysql://" + host.trim() + ":3306/" + db.trim() +
"?serverTimezone=" + now.getTimeZone().getID();
我根据上面引用的文档选择了serverTimezone
:
serverTimezone
Override detection/mapping of time zone. Used when time zone from server doesn't map to Java time zone
Since version: 3.0.2
是的,在我的情况下这实际上不是真的 - 我的 MySql 服务器设置为 UTC,它确实映射到客户端,但是因为我不希望它映射,所以我尝试了这个并且它有效.我没有尝试其他时区参数,因为这个参数立即起作用,但是 noTimezoneConversionForDateType
或其他时区参数之一很有可能起作用。
如果有人对此解决方案有疑虑,请提出来。我想我有点作弊,但我现在想不出任何真正危险的副作用。