【发布时间】:2020-05-03 20:52:29
【问题描述】:
我在使用 Jooq 的前 1 天从 SQL 中的日期列中得到 2019-09-01。我认为这是因为我的应用程序(操作系统级别和 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 程序,即更新数据库的程序,在将其添加到数据库之前并没有真正进行任何时区转换。它根据操作系统时区获取日期,然后使用该日期。因此,如果它增加了 2019 年 9 月 1 日,我预计会在 2019 年 9 月 1 日回来。我试过select date( kpisd1 ),但也没有用。即使我打印出原始的 java.sql.Date,它也与数据库不匹配,这意味着它可能正在 JDBC 内部进行转换,我猜。有什么想法吗?
我唯一的其他选择是将数据库时区从 UTC 转换为“美国/东部”(以匹配我的应用程序服务器上的时区),但我需要研究其后果,所以我尽量不要急于如此激烈的一步(这是生产环境)。
【问题讨论】:
-
您是否在 MySQL 中使用
datetime来存储不需要时间的日期?为什么?您可能还想create a Minimal, Reproducible Example,以便我们确切地看到您正在尝试什么。 -
jOOQ 在 JDBC 之上没有做任何额外的时区转换魔法,所以这更像是你的 JDBC 驱动程序的工作方式。有很多方法可以解决这个问题,理想情况下不是基于每个查询,而是通过将所有时区设置为 UTC...
-
@OleV.V.
datetime使用而不是简单的date是我们使用的其他数据库系统的保留,我预计。老实说,这无关紧要,因为我们的 C 代码不在乎,只是照原样处理。无论如何,关键是在一个时区(不是 UTC)中运行的应用程序与 UTC 中的数据库相对应。 -
@LukasEder 我不能在任何地方都使用 UTC,现在不能。也许我们应该从一开始就这样做,但使用我们当地的时区总是更容易,所以这就是我们所做的。我只是错过了设置此数据库时的影响,没有意识到在数据库级别不将时区从 UTC 更改为我们的本地时区的后果。所以,我真的需要在每个查询的基础上执行此操作,除非这些方法或非常糟糕的想法。您能否指出正确的方向,以便我评估其中的一些想法,看看是否适合我的用例?
-
MySQL 的 JDBC 驱动程序有 很多 的 JDBC URL 属性,用于控制时区的行为。我建议您查看dev.mysql.com/doc/connector-j/5.1/en/… 并测试一些属性,例如
useTimezone或noTimezoneConversionForDateType。