Oracle UTC时间

时间:2013-02-20 15:12:50

标签: sql oracle oracle11g timezone

我正在尝试从UTC-5(NY)的数据库中读取Oracle TIMESTAMP WITH TIMEZONE作为UTC。

甲骨文让我发疯:

SELECT 
from_tz(MAX(TIMESTAMPWITHTIMEZONE),'UTC'),
SYS_EXTRACT_UTC(MAX(TIMESTAMPWITHTIMEZONE)),
SYS_EXTRACT_UTC(systimestamp), 
SYSTIMESTAMP AT TIME ZONE 'UTC'
FROM TABLE

结果:

  • SYS_EXTRACT_UTC(systimestamp)给了我:2013-02-20 14:59:04,这可能是对的。

  • SYSTIMESTAMP AT TIME ZONE 'UTC'给了我:2013-02-20 15:59:04这是我自己的当地柏林 - 无论

现在我希望TIMESTAMPWITHTIMEZONE(TIMESTAMP(6))为UTC

  • SYS_EXTRACT_UTC(MAX(TIMESTAMPWITHTIMEZONE))2013-02-20 08:55:01

  • from_tz(MAX(TIMESTAMPWITHTIMEZONE),'UTC')2013-02-20 10:55:01

Srly。甲骨文。我想要UTC。

哪一个是正确的?或者,还有更好的方法?

2 个答案:

答案 0 :(得分:8)

功能不同:

  • SYS_EXTRACT_UTCTIMESTAMP WITH TIMEZONE转换为TIMESTAMP(已推断但缺少时区= UTC)。
  • FROM_TZTIMESTAMP转换为TIMESTAMP WITH TIMEZONE

当应用于单个值时,这些函数通常会返回不同的结果:

SQL> SELECT sys_extract_utc(localtimestamp) ext,
  2         from_tz(localtimestamp, 'UTC')  from_tz
  3    FROM dual;

EXT                   FROM_TZ
--------------------- ------------------------
2013/02/20 15:34:24   2013/02/20 16:34:24 UTC

在第一种情况下,TIMESTAMP 隐式给定服务器的时区,然后转换为UTC时区的等效时间戳。请注意,通常您应远离隐式转换。

在第二种情况下,时区之间没有计算:FROM_TZ函数将地理位置添加到时间点变量。

顺便说一句,您的示例中缺少某些内容:您无法在FROM_TZ类型的变量上应用TIMESTAMP WITH TIMEZONE函数(在9ir2和11ir2上测试):

SQL> select from_tz(systimestamp, 'UTC') from dual;

select from_tz(systimestamp, 'UTC') from dual

ORA-00932: inconsistent datatypes: 
   expected TIMESTAMP got TIMESTAMP WITH TIME ZONE

修改以下评论:

假设您的专栏有时间TIMESTAMP并且知道他们引用了纽约时区,您可以使用AT TIME ZONE表达式转换为UTC

SQL> SELECT localtimestamp,
  2         from_tz(localtimestamp, 'America/New_York') AT TIME ZONE 'UTC' utc
  3    FROM dual;

LOCALTIMESTAMP        UTC
--------------------- ------------------------
2013/02/20 17:09:09   2013/02/20 22:09:09 UTC

答案 1 :(得分:0)

从Oracle 18c开始,您可以使用TO_UTC_TIMESTAMP_TZ函数:

  

TO_UTC_TIMESTAMP_TZ函数将表示为字符串的任何有效ISO 8601日期转换为TIMESTAMP WITH TIMEZONE,可以选择将其用作SYS_EXTRACT_UTC函数的输入。

SELECT TO_UTC_TIMESTAMP_TZ(col_name)
FROM tab_name;