代码之家  ›  专栏  ›  技术社区  ›  Matthew Watson

Oracle中的时区偏移

  •  2
  • Matthew Watson  · 技术社区  · 14 年前

    使用Oracle9.2i,我需要从一个时区相对于另一个时区获得不同日期的偏移量,以前我是这样做的

    select
    (TO_DATE('10-Oct-2010 09:00:00','DD-Mon-YYYY HH24:Mi:SS') - 
                  TO_DATE(TO_CHAR(FROM_TZ(to_timestamp( '10-Oct-2010 09:00:00','DD-Mon-YYYY HH24:Mi:SS'), 'Australia/Victoria')
                    AT TIME ZONE 'Australia/West'        , 'DD-Mon-YYYY HH24:Mi:SS'),'DD-Mon-YYYY HH24:Mi:SS'))
    from dual
    

    虽然有点凌乱,但很适合我的需要。现在的问题是,这似乎没有考虑到日光节约。10月10日维多利亚州和西澳大利亚州的时差实际上是3小时,而不是2小时(我的查询目前返回)。

    现在这很奇怪,正如我认为的那样,从“TZ”开始就意味着要处理DST。更奇怪的是,如果我把格林尼治标准时间与格林尼治标准时间相比较,我会得到正确的结果。

    select FROM_TZ(to_timestamp( '10-Oct-2010 00:00:00','DD-Mon-YYYY HH24:Mi:SS'), 'GMT') AT TIME ZONE 'Australia/West'
    from dual
    
    FROM_TZ(TO_TIMESTAMP('10-OCT-2 
    ------------------------------ 
    10-OCT-10 08.00.00.000000000 AM AUSTRALIA/WEST 
    

    对的

    select FROM_TZ(to_timestamp( '10-Oct-2010 00:00:00','DD-Mon-YYYY HH24:Mi:SS'), 'GMT') AT TIME ZONE 'Australia/Victoria'
    from dual
    
    FROM_TZ(TO_TIMESTAMP('10-OCT-2 
    ------------------------------ 
    10-OCT-10 11.00.00.000000000 AM AUSTRALIA/VICTORIA 
    

    对的

    select FROM_TZ(to_timestamp( '10-Oct-2010 00:00:00','DD-Mon-YYYY HH24:Mi:SS'), 'Australia/Victoria') AT TIME ZONE 'Australia/West'
    from dual
    
    FROM_TZ(TO_TIMESTAMP('10-OCT-2 
    ------------------------------ 
    09-OCT-10 10.00.00.000000000 PM AUSTRALIA/WEST 
    

    错了。2010年10月10日上午00:00:00在澳大利亚西部,时间为10月9日上午09:00.00。

    所以问题是,这是一个bug吗?或者我只是在用这个词吗?时区错误?

    谢谢。

    更新:

    我认为这可能是to-char函数中的一个bug,它似乎得到了错误的tz偏移。虽然from-tz可以正确地从格林尼治标准时间更改为维多利亚时间,但当您试图从该时间中提取Tz偏移量时,它会说它是+10,当它应该是+11时。

    select TO_CHAR(FROM_TZ(to_timestamp( '10-Oct-2010 00:00:00','DD-Mon-YYYY HH24:Mi:SS'), 'Australia/Victoria'), 'TZH:TZM')
          ,FROM_TZ(to_timestamp( '10-Oct-2010 00:00:00','DD-Mon-YYYY HH24:Mi:SS'), 'GMT') AT TIME ZONE 'Australia/Victoria'
    from dual
    
    TO_CHAR(FROM_TZ(TO_TIMESTAMP('                                              FROM_TZ(TO_TIMESTAMP('10-OCT-2 
    --------------------------------------------------------------------------- ------------------------------ 
    +10:00                                                                      10-OCT-10 11.00.00.000000000 AM AUSTRALIA/VICTORIA 
    
    1 回复  |  直到 11 年前
        1
  •  1
  •   Jeffrey Kemp    11 年前

    据我所知,TZH和TZM是时区字符串的缩写,但它们不考虑夏令时。维多利亚的时区是+10:00。

    也许TZD就是你想要的。

    TZD夏令时信息。这个 TZD值是一个缩短的时区 带夏令时的字符串 信息。

    http://download.oracle.com/docs/cd/B28359_01/olap.111/b28126/dml_commands_1029.htm

    select TO_CHAR(FROM_TZ(ts, 'Australia/Victoria'), 'TZH:TZM TZD')
          ,FROM_TZ(ts, 'GMT') AT TIME ZONE 'Australia/Victoria'
    from (select to_timestamp( '10-Oct-2010 00:00:00','DD-Mon-YYYY HH24:Mi:SS')
                 as ts
          from dual);
    
    +10:00 EST    10/10/2010 10:00:00.000000000 AM +10:00