3

我正在尝试TIMESTAMP WITH TIMEZONE从 UTC-5 (NY) 的数据库中读取 Oracle 作为 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

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

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

4

2 回答 2

8

功能不同:

  • SYS_EXTRACT_UTC将 a 转换TIMESTAMP WITH TIMEZONE为 a TIMESTAMP(推断但不存在时区=UTC)。
  • FROM_TZ将 a 转换TIMESTAMP为 aTIMESTAMP 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

编辑以下评论:

在您的情况下,假设您的列是 time TIMESTAMP,并且知道它们指的是 NY 时区,您可以使用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
于 2013-02-20T15:39:48.757 回答
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;
于 2018-04-10T19:39:52.927 回答