【问题标题】:Oracle UTC Time甲骨文世界标准时间
【发布时间】:2013-02-20 15:12:50
【问题描述】:

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

Oracle 快把我逼疯了:

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

严肃点。甲骨文。我想要 UTC。

哪一个是正确的?还是有更好的办法?

【问题讨论】:

标签: sql oracle oracle11g timezone


【解决方案1】:

功能不同:

  • 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

【讨论】:

  • 好的,现在变得更容易理解了,我知道 DBTimezone 是 UTC-5 并且时间戳(现在可能没有时区)被插入到那个时区。 - 我应该做的就是收集那个时间戳,再加上 5 个小时来获得 UTC?我应该用什么来获得 UTC?谢谢你的时间:)
  • 您可以使用 AT TIME ZONE 表达式将 a 从一个时区转换为另一个时区,请参阅我的更新答案。
【解决方案2】:

从 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;

【讨论】:

    猜你喜欢
    • 2011-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-17
    相关资源
    最近更新 更多