简体   繁体   English

Oracle UTC时间

[英]Oracle UTC Time

I'm trying to read an Oracle TIMESTAMP WITH TIMEZONE from a database in UTC-5 (NY) as UTC. 我正在尝试从UTC-5(NY)的数据库中读取TIMESTAMP WITH TIMEZONE的Oracle TIMESTAMP WITH TIMEZONE作为UTC。

Oracle is driving me crazy: 甲骨文让我抓狂:

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

Results: 结果:

  • SYS_EXTRACT_UTC(systimestamp) gives me: 2013-02-20 14:59:04 , which is probably right. SYS_EXTRACT_UTC(systimestamp)给了我: 2013-02-20 14:59:04 ,这可能是正确的。

  • SYSTIMESTAMP AT TIME ZONE 'UTC' gives me: 2013-02-20 15:59:04 which is my own local Berlin - whatever SYSTIMESTAMP AT TIME ZONE 'UTC'给了我: 2013-02-20 15:59:04这是我自己的当地柏林 - 无论如何

Now I want to have TIMESTAMPWITHTIMEZONE (TIMESTAMP(6)) as UTC 现在我希望将TIMESTAMPWITHTIMEZONE(TIMESTAMP(6))作为UTC

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

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

Srly. Srly。 Oracle. 甲骨文。 I want UTC. 我想要UTC。

Which one is the right one? 哪一个是正确的? Or is there a better way? 或者,还有更好的方法?

The functions are different: 功能不同:

  • SYS_EXTRACT_UTC converts a TIMESTAMP WITH TIMEZONE to a TIMESTAMP (with inferred but absent timezone=UTC). SYS_EXTRACT_UTCTIMESTAMP WITH TIMEZONE转换为TIMESTAMP (推断但没有时区= UTC)。
  • FROM_TZ converts a TIMESTAMP to a TIMESTAMP WITH TIMEZONE FROM_TZTIMESTAMP转换为TIMESTAMP WITH TIMEZONE

These functions when applied to a single value will in general return a different result: 应用于单个值时,这些函数通常会返回不同的结果:

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

In the first case the TIMESTAMP is implicitly given the timezone of the server and then transformed into the equivalent timestamp at the UTC timezone. 在第一种情况下, TIMESTAMP隐式地赋予服务器的时区,然后转换为UTC时区的等效时间戳。 Note that in general you should stay away from implicit conversions. 请注意,通常您应远离隐式转换。

In the second case there is no computation between timezones: the FROM_TZ function adds the geographical location to a point in time variable. 在第二种情况下,时区之间没有计算: FROM_TZ函数将地理位置添加到时间点变量。

By the way there is something missing in your example: you can't apply the FROM_TZ function on a variable of type TIMESTAMP WITH TIMEZONE (tested on 9ir2 and 11ir2): 顺便说一句,你的例子中缺少一些东西:你不能在TIMESTAMP WITH TIMEZONE类型的变量上应用FROM_TZ函数(在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

Edit following comment: 编辑以下评论:

In your case assuming that your column are of time TIMESTAMP , and knowing that they refer to the NY timezone, you could use the AT TIME ZONE expression to convert to UTC : 在您的情况下,假设您的列具有时间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

From Oracle 18c you could use TO_UTC_TIMESTAMP_TZ function: 从Oracle 18c开始,您可以使用TO_UTC_TIMESTAMP_TZ函数:

The TO_UTC_TIMESTAMP_TZ function converts any valid ISO 8601 date represented as a string into a TIMESTAMP WITH TIMEZONE, which can optionally be used as input to the SYS_EXTRACT_UTC function. TO_UTC_TIMESTAMP_TZ函数将表示为字符串的任何有效ISO 8601日期转换为TIMESTAMP WITH TIMEZONE,可以选择将其用作SYS_EXTRACT_UTC函数的输入。

SELECT TO_UTC_TIMESTAMP_TZ(col_name)
FROM tab_name;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM