oraclesql:at时区不能正确转换1905年6月1日之前的时间戳

fslejnso  于 2021-07-24  发布在  Java
关注(0)|答案(1)|浏览(422)

我需要将存储在数据库中的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中有解决这个问题的方法吗?

snz8szmq

snz8szmq1#

新加坡曾多次改变时区,见新加坡标准时间。

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 epoch(1970-01-01 00:00:00 utc)之后出现的时间戳一致。数据库用一个值得注意的位置标记每个时区,并记录该位置的所有已知时钟转换。虽然1970年是一个有点武断的截止日期,但在计算机计时开始流行之前,由于各种各样的当地做法,要将截止日期提前十年或二十年,仍然存在重大挑战。
1970年之前的时钟转换记录每个时区,因为大多数系统支持1970年之前的时间戳,如果1970年之前的转换忽略了数据条目,则可能会出现错误行为。然而,该数据库不是为需要准确处理各地过去所有时间的应用程序而设计的,也不足以满足这些应用程序的需要,因为要记录1970年以前的民用计时的所有细节,将需要太多的努力和猜测。虽然数据库范围之外的一些信息收集在与数据库一起分发的文件后台区域中,但此文件的可靠性较低,不一定遵循数据库准则。
我认为没有一个简单的解决办法。

相关问题