围绕夏令时 (DST) 的奇怪 sybase 行为
Strange sybase behavior around daylight savings time (DST)
我有一个我不明白的奇怪的 sybase 行为。
情况
我有一个 table (MY_TABLE),其中有几列 smalldatetime。为了便于说明,我们假设以下 table 和数据:
MY_TABLE||ID |TS_INIT |TS_LASTCHANGE |MY_TEXT |
||4711|3/31/2013 12:00:00 AM|3/31/2013 3:00:00 AM|someText|
TS_INIT 和 TS_LASTCHANGE 的类型是 smalldatetime .
当执行下面的语句时,我得到了上面的结果:
SELECT ID, TS_INIT, TS_LASTCHANGE MY_TEXT
FROM MY_TABLE
WHERE ID = 4711
go
我的客户端是 运行 UTC+1(柏林)并且启用了夏令时 (DST)。
我不确定服务器在哪个时区 运行 以及是否启用了 DST。
问题
当我执行这个时(注意是03:00h):
SELECT ID, TS_INIT, TS_LASTCHANGE MY_TEXT
FROM MY_TABLE
WHERE ID = 4711 AND TS_LASTCHANGE = "2013-03-31 03:00:00:000"
go
我得到 NO 结果但是当我执行这个时(注意这次是 02:00h):
SELECT ID, TS_INIT, TS_LASTCHANGE MY_TEXT
FROM MY_TABLE
WHERE ID = 4711 AND TS_LASTCHANGE = "2013-03-31 02:00:00:000"
go
我再次得到上面的结果,即 TS_LASTCHANGE 是
3/31/2013 3:00:00 AM
请注意,结果打印 03:00h,即使我查询的是 02:00h。
为什么第一个查询没有返回任何结果,即使 应该 是一个匹配,为什么第二个查询返回结果,即使应该 没有匹配?!
还要注意 3/31/2013 3:00:00 AM 是夏令时的第一个时刻(至少在 2013 年)和 3 /31/2013 2:00:00 AM 根本不应该存在,因为当从冬令时过渡到夏令时,时钟从 01:59:59 切换到03:00:00(根据 this 站点)。
数据库:Adaptive Server Enterprise V15.0.3
客户端:Aqua Data Studio V16.0.5
编辑:
当查询 TS_INIT 时,一切都按预期工作(只有 3/31/2013 12:00:00 AM)
的结果
Aqua Data Studio 是在 Java.
中编写的
您遇到的问题与 Java 知道时区的事实有关,而数据库在存储日期和时间时没有时区的概念。当时间从数据库返回时,数据库的 JDBC 驱动程序将其置于 Java 日期,并假定时区无关紧要。当您尝试显示 JVM 认为无效的时间时会出现问题,因此会显示有效日期,这基本上会将时间推迟一个小时。 2015 年夏令时从 3 月 8 日凌晨 2 点开始,您的其中一行包含根据 JVM 无效的日期。
这是 Java 的一个已知设计问题,他们正在尝试使用 JSR-310 修复此问题以包含在 Java SE 8 中。有了这个,他们将拥有 LocalDate、OffsetDate和 ZonedDate。您可以在此处阅读更多相关信息...
https://today.java.net/pub/a/today/2008/09/18/jsr-310-new-java-date-time-api.html#jsr-310-datetime-concepts
https://jcp.org/en/jsr/detail?id=310
http://docs.google.com/View?id=dfn5297z_8d27fnf
解决方法
唯一的解决方法是可能通过将 JVM 中的时区设置为 GMT 来欺骗 JVM。如果你是 运行 ADS 16 on Windows,并且你用桌面上的快捷图标启动 ADS(运行 datastudio.exe),那么你需要修改 datastudio.ini 文件在你的文件夹中。为 vmarg.5=-Duser.timezone=gmt
添加一个新条目
此 link 解释了查找数据的位置 studio.ini
https://www.aquaclusters.com/app/home/project/public/aquadatastudio/wikibook/Documentation14/page/50/Launcher-Memory-Configuration#windows
完成更改后,重新启动 ADS。然后转到帮助->关于->系统:并仔细检查您的 user.timezone 设置并确保它是 GMT。然后试一试。
通过上述更改,涉及时区的应用程序可能会产生副作用,例如在 Table 数据编辑器 -> 插入当前日期和时间,这将显示 GMT 时间...因此会有一个偏移量。
我有一个我不明白的奇怪的 sybase 行为。
情况
我有一个 table (MY_TABLE),其中有几列 smalldatetime。为了便于说明,我们假设以下 table 和数据:
MY_TABLE||ID |TS_INIT |TS_LASTCHANGE |MY_TEXT |
||4711|3/31/2013 12:00:00 AM|3/31/2013 3:00:00 AM|someText|
TS_INIT 和 TS_LASTCHANGE 的类型是 smalldatetime .
当执行下面的语句时,我得到了上面的结果:
SELECT ID, TS_INIT, TS_LASTCHANGE MY_TEXT
FROM MY_TABLE
WHERE ID = 4711
go
我的客户端是 运行 UTC+1(柏林)并且启用了夏令时 (DST)。 我不确定服务器在哪个时区 运行 以及是否启用了 DST。
问题
当我执行这个时(注意是03:00h):
SELECT ID, TS_INIT, TS_LASTCHANGE MY_TEXT
FROM MY_TABLE
WHERE ID = 4711 AND TS_LASTCHANGE = "2013-03-31 03:00:00:000"
go
我得到 NO 结果但是当我执行这个时(注意这次是 02:00h):
SELECT ID, TS_INIT, TS_LASTCHANGE MY_TEXT
FROM MY_TABLE
WHERE ID = 4711 AND TS_LASTCHANGE = "2013-03-31 02:00:00:000"
go
我再次得到上面的结果,即 TS_LASTCHANGE 是
3/31/2013 3:00:00 AM
请注意,结果打印 03:00h,即使我查询的是 02:00h。
为什么第一个查询没有返回任何结果,即使 应该 是一个匹配,为什么第二个查询返回结果,即使应该 没有匹配?!
还要注意 3/31/2013 3:00:00 AM 是夏令时的第一个时刻(至少在 2013 年)和 3 /31/2013 2:00:00 AM 根本不应该存在,因为当从冬令时过渡到夏令时,时钟从 01:59:59 切换到03:00:00(根据 this 站点)。
数据库:Adaptive Server Enterprise V15.0.3
客户端:Aqua Data Studio V16.0.5
编辑: 当查询 TS_INIT 时,一切都按预期工作(只有 3/31/2013 12:00:00 AM)
的结果Aqua Data Studio 是在 Java.
中编写的
您遇到的问题与 Java 知道时区的事实有关,而数据库在存储日期和时间时没有时区的概念。当时间从数据库返回时,数据库的 JDBC 驱动程序将其置于 Java 日期,并假定时区无关紧要。当您尝试显示 JVM 认为无效的时间时会出现问题,因此会显示有效日期,这基本上会将时间推迟一个小时。 2015 年夏令时从 3 月 8 日凌晨 2 点开始,您的其中一行包含根据 JVM 无效的日期。
这是 Java 的一个已知设计问题,他们正在尝试使用 JSR-310 修复此问题以包含在 Java SE 8 中。有了这个,他们将拥有 LocalDate、OffsetDate和 ZonedDate。您可以在此处阅读更多相关信息...
https://today.java.net/pub/a/today/2008/09/18/jsr-310-new-java-date-time-api.html#jsr-310-datetime-concepts https://jcp.org/en/jsr/detail?id=310 http://docs.google.com/View?id=dfn5297z_8d27fnf
解决方法
唯一的解决方法是可能通过将 JVM 中的时区设置为 GMT 来欺骗 JVM。如果你是 运行 ADS 16 on Windows,并且你用桌面上的快捷图标启动 ADS(运行 datastudio.exe),那么你需要修改 datastudio.ini 文件在你的文件夹中。为 vmarg.5=-Duser.timezone=gmt
此 link 解释了查找数据的位置 studio.ini https://www.aquaclusters.com/app/home/project/public/aquadatastudio/wikibook/Documentation14/page/50/Launcher-Memory-Configuration#windows
完成更改后,重新启动 ADS。然后转到帮助->关于->系统:并仔细检查您的 user.timezone 设置并确保它是 GMT。然后试一试。 通过上述更改,涉及时区的应用程序可能会产生副作用,例如在 Table 数据编辑器 -> 插入当前日期和时间,这将显示 GMT 时间...因此会有一个偏移量。