oracle如何在内部存储带时区的时间戳

时间:2014-04-26 09:40:19

标签: oracle timestamp-with-timezone

基于Oracle文档,它根据数字在内部存储时区的不同部分和时区。我读了这篇文章http://www.orafaq.com/wiki/Timestamp,它解释了时间戳内部格式的算法。所以我做了一个简单的测试来验证它。

 SQL> create table tz_test(id number, tz timestamp with time zone);

 Table created.

 SQL> insert into tz_test values(1, timestamp '1999-10-29 21:00:00 -7:00');

 1 row created.

 SQL> insert into tz_test values(2, timestamp '1999-10-29 21:00:00 US/Pacific');

 1 row created.

 SQL> select id, dump(tz, 10) from tz_test where tz=timestamp '1999-10-29 21:00:00 -7:00';

    ID     DUMP(TZ,10)
 --------------------------------------------------------------------------------

     1     Typ=181 Len=13: 119,199,10,30,5,1,1,0,0,0,0,13,60

     2     Typ=181 Len=13: 119,199,10,30,5,1,1,0,0,0,0,137,156

orafaq中的文章讨论了oracle如何存储时区偏移量,并且我的第一行测试证明了这一点。但是没有关于如何存储时区文字的信息。所以我热衷于了解它。我也想在内部了解oracle如何评估时间戳' 1999-10-29 21:00:00 -7:00'和时间戳' 1999-10-29 21:00:00美国/太平洋地区'是相同的。

2 个答案:

答案 0 :(得分:2)

它们似乎是来自time zone file的区域ID,例如$ORACLE_HOME/oracore/zoneinfo/timezone_14.dat

In this SQL Fiddle,时区为PST8PDT的值的最后两个字节为0x830x64;它与MOS文档ID 414590.1建议的值相匹配。

我看不到任何列出所有可能值的引用,或者检查时区文件的任何明显方法。它似乎没有记录,这对于内部格式来说并不合理。您可以使用相同的方法找出您感兴趣的值或所有值,但我不确定您为什么要这样做。

您可能会发现另一个有用的支持文档,340512.1,这是一个关于时间戳和时区的常见问题解答。

要将地区名称转换为偏移值,您可以使用the tz_offs function,但它会使用当前日期 - 因此您获得的答案取决于您是在冬季还是夏季提出要求。要获取特定日期的偏移量,您需要将该时间戳与UTC时间戳进行比较。而且你不可能走另一条路,因为多个时区区域映射了相同的偏移量。

答案 1 :(得分:1)

TIMESTAMP '1999-10-29 21:00:00 -7:00'TIMESTAMP'1999-10-29 21:00:00 US/Pacific' 相同。

例如,您在运行此查询时看到了区别:

SELECT 
    TIMESTAMP '1999-12-29 21:00:00 -7:00', 
    TIMESTAMP '1999-12-29 21:00:00 US/Pacific',
    TIMESTAMP '1999-06-29 21:00:00 -7:00', 
    TIMESTAMP '1999-06-29 21:00:00 US/Pacific'
FROM dual;

29.12.1999 21:00:00.000000000 -07:00    
29.12.1999 21:00:00.000000000 -08:00    
29.06.1999 21:00:00.000000000 -07:00    
29.06.1999 21:00:00.000000000 -07:00

US/Pacific考虑夏令时,-7:00没有!