如何在 Oracle 中处理闰秒
Posted
技术标签:
【中文标题】如何在 Oracle 中处理闰秒【英文标题】:How to handle leap seconds in Oracle 【发布时间】:2015-06-30 10:47:53 【问题描述】:今晚时钟将增加闰秒,当天最后一小时的最后一分钟将有 61 秒。
2015-06-30 23:59:60
但是,Oracle 最多只支持一分钟 60 秒:
TO_DATE( '2015-06-30 23:59:60', 'YYYY-MM-DD HH24:MI:SS' )
错误:
ORA-01852: seconds must be between 0 and 59
和
SELECT TO_DATE( '2015-06-30 23:59:59', 'YYYY-MM-DD HH24:MI:SS' ) + INTERVAL '1' SECOND AS Incr_Second_Before,
TO_DATE( '2015-07-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS' ) - INTERVAL '1' SECOND AS Decr_Second_After
FROM DUAL
给出输出:
| INCR_SECOND_BEFORE | DECR_SECOND_AFTER |
|------------------------|------------------------|
| July, 01 2015 00:00:00 | June, 30 2015 23:59:59 |
有没有办法在 Oracle 中处理闰秒?
【问题讨论】:
您到底想处理什么?在第 61 秒内不能存在日期/时间戳;那么,如果操作系统时钟允许,您是否会问 sysdate/systimestamp 会显示什么?或者您是否正在获取第 61 秒的外部数据并想要解释/存储它? 如果我从2015-06-30 23:59:60
的外部源获取数据,它将出错并且无法存储。如果我这样做SELECT EXTRACT( SECOND FROM TIMESTAMP '2015-07-01 00:00:00.000' - TIMESTAMP '2015-06-30 23:59:59.000' ) FROM DUAL
,答案应该是2
,但Oracle 会返回1
。我认为没有什么可以做的,但如果有什么地方可以用闰秒列表更新,那么 Oracle 会考虑到这一点,那么知道它会很有用。
OK,接着看MOS note 2019397.2;和 730795.1。虽然看起来什么都做不了。除了像用:59
替换:60
这样的黑客我想......
@MT0 实际上,这仅在时间等于 UTC 的时区是正确的。闰秒同时添加到所有时区。因此,事实上,Oracle 的错误消息在这种特定情况下在世界大部分地区确实是正确的,因为没有选择时区。然而,在所有时区,6 月 30 日和 7 月 1 日的秒数总和应该是 172801 而不是 172800。
如果您真的关心闰秒,那么最好将时间存储为Julian Date 值。
【参考方案1】:
来自MOS-
在时间戳列中插入闰秒失败,出现 ORA-01852(Doc ID 1553906.1)
适用于:
Oracle 数据库 - 企业版 - 版本 8.1.7.4 及更高版本
Oracle 数据库 - 标准版 - 版本 8.1.7.4 及更高版本
本文档中的信息适用于任何平台。
症状:
尝试将闰秒插入时间戳列,失败并显示: ORA-01852: 秒数必须在 0 到 59 之间
原因
不能在日期或时间戳中存储 >59 秒的值 数据类型
解决方案
要解决此问题,可以将闰秒记录存储在 varchar2 数据类型,例如
SQL> create table test (val number, t varchar2(30));
Table created.
SQL> insert into test values(123, '2012-06-30T23:59:60.000000Z');
1 row created.
不是最好的解决方案,而是唯一的解决方案。
【讨论】:
这是一个糟糕的解决方案,并且与在 Oracle 中处理日期的所有最佳实践相矛盾。如果这是一个关键问题,那么我宁愿找到一种方法来使用修改后的时间戳算法来正确表达一个或多个闰秒之间的秒数差异,我很惊讶甲骨文公司没有这样做。跨度> @DavidAldridge 我同意。虽然,他们还有其他关键问题,不是特别与 RDBMS 相关,但他们已经发布了几个补丁,这些闰秒问题列出了从 100% CPU 利用率到直接服务器不可用风险。所以我只是认为他们有更大的鱼要炸。 虽然这是存储闰秒的“解决方案”(我同意它违反所有最佳实践);它不能解决跨闰秒的日期算术的额外问题 - 然后您必须创建自己的函数来处理算术并有一个闰秒查找表来对计算进行调整。看起来 Oracle 建议您必须从头开始重新实现日期/时间处理才能解决此问题。以上是关于如何在 Oracle 中处理闰秒的主要内容,如果未能解决你的问题,请参考以下文章