首页 > 解决方案 > Oracle SQL:在 1905 年 6 月 1 日之前的时区无法正确转换时间戳

问题描述

在我的前端服务可以使用它之前,我需要将存储在我的数据库中的 UTC 格式的时间戳转换为 SGT 格式(UTC + 8)。

我使用的查询是这样的:

SELECT DATE_OF_PURCHASE at time zone 'Asia/Singapore' FROM PROPERTY_LISTINGS;

只要时间戳在 1905 年 6 月 1 日之前,它就可以正常工作。在那之前的任何年份,我都会​​得到一个转换后的时间戳,它总是落后 25 秒。

一个例子:

1899-09-02 17:04:35.000000 in UTC

转换回 SGT 应产生:

1899-09-03 00:00:00.000000 in SGT

运行上面的查询at time zone给出:

1899-09-02 23:59:35.000000 +06:55:25

这是25秒。这导致返回的时间戳是一整天的休息时间,这是意料之中的。SQL中是否有解决方法?

标签: sqloracletimezone

解决方案


新加坡多次更改时区,请参阅新加坡标准时间

Asia/Singapore  6:55:25 -       LMT     1901 Jan  1
                6:55:25 -       SMT     1905 Jun  1 # Singapore M.T.
                7:00    -       +07     1933 Jan  1
                7:00    0:20    +0720   1936 Jan  1
                7:20    -       +0720   1941 Sep  1
                7:30    -       +0730   1942 Feb 16
                9:00    -       +09     1945 Sep 12
                7:30    -       +0730   1982 Jan  1
                8:00    -       +08

当您查看 Oracle文档时,它会显示:时区偏移量是本地时间和 UTC 之间的差异(以小时和分钟为单位)。在时区转换中似乎根本不支持/考虑秒。

Oracle 使用 IANA 时区数据库,该数据库指出:

tz数据库的范围

tz 数据库试图记录跟踪民用时间的所有基于计算机的时钟的历史和预测的未来。它通过将世界划分为时区来组织时区和夏令时数据,这些时区的时钟都同意在 POSIX 纪元 (1970-01-01 00:00:00 UTC) 之后发生的时间戳。数据库用一个显着的位置标记每个时区,并记录该位置的所有已知时钟转换。尽管 1970 年是一个有点武断的分界线,但将分界线提前一到两年仍然存在重大挑战,因为在计算机计时流行之前,当地的做法多种多样。

为每个时区记录 1970 年之前的时钟转换,因为大多数系统支持 1970 年之前的时间戳,如果在 1970 年之前的转换中省略数据条目,则可能会出现异常行为。然而,该数据库不是为需要准确处理所有过去时间的应用程序而设计的,也不足以满足这些应用程序的需求,因为要记录 1970 年前民用计时的所有细节需要付出太多的努力和猜测。尽管数据库范围之外的一些信息被收集在与数据库一起分发的文件后台区域中,但该文件的可靠性较低,并且不一定遵循数据库指南。

我不认为有一个简单的解决方案。


推荐阅读