繁体   English   中英

Oracle SQL:将时间戳转换为UTC

[英]Oracle SQL: converting timestamp to UTC

我有一个简单的选择查询,如下所示,但我注意到我回到了区域时间。 如何在我选择的陈述中转换为UTC?

select myTimeStamp, MyName, MyBranch from tableA

结果:“ 27/03/2014 15:15:26”“约翰”,“伦敦”

我尝试使用sys_extract_utc(myTimeStamp),但出现错误

sql命令未正确结束

myTimestamp列的类型为“ date”。

select cast(mytimestamp as timestamp) at time zone 'UTC', 
       MyName, 
       MyBranch 
from tableA

因为mytimestamp实际上是date而不是时间戳,所以您需要转换它。 这样做使Oracle假定存储在mytimestamp中的信息位于服务器的时区中-如果不是这种情况,则需要使用Madhawas的解决方案。

根据类型,根据myTimestamp的数据类型,Oracle从哪个时区转换有一些陷阱。

带时区的时间戳

It Just Works™。 a_horse_with_no_name在这里有正确的答案。

带本地时区的时间戳

它被隐式转换为带时区的时间戳 ,然后是Just Just™。 同样, a_horse_with_no_name就在这里。

时间戳记

尽管它也被隐式转换为带有时区的时间戳 ,但默认情况下分配的时区是会话时区(与数据库时区相反)。

  • 对此的显式调用是myTimestamp at local
  • 另外(可能更好),您可以按照Madhawas所说的做,并使用from_tz函数显式地建立一个具有与会话不同的显式时区的值。

日期

到目前为止 ,尝试执行上述任何操作都会失败,如下所述:

  • myTimestamp at time zone 'UTC'
    ORA-30084:具有时区修饰符的datetime主数据类型无效

  • from_tz(myTimestamp, 'America/New_York')
    ORA-00932:数据类型不一致:预期的时间戳记是DATE

这里的解决方案是首先将日期转换为时间戳

select from_tz(cast(myTimestamp as timestamp), 'America/New_York') from tableA

样例脚本

以下脚本说明了该行为。 请注意,在我的系统上, dbtimezone是美国/中央,而sessiontimezone是GMT-05:00。

我还使用to_char来转换输出,因为我发现某些工具会以微妙的方式更改结果时间戳,尤其是如果它们没有良好的时间戳支持(如今很少见,但仍然可能是一个问题)。

alter session set nls_date_format = 'YYYY-MM-DD HH24:MI:SS'
/
alter session set nls_timestamp_format = 'YYYY-MM-DD HH24:MI:SS'
/
alter session set nls_timestamp_tz_format = 'YYYY-MM-DD HH24:MI:SS TZR'
/

select dbtimezone
      ,sessiontimezone
      ,to_char(timestamp '2017-01-01 06:00:00') as ts
      ,to_char(timestamp '2017-01-01 06:00:00' at local) as ts_at_local
      ,to_char(timestamp '2017-01-01 06:00:00' at time zone dbtimezone) as ts_at_db
      ,to_char(timestamp '2017-01-01 06:00:00' at time zone sessiontimezone) as ts_at_session
 from dual
/

我的系统上的输出如下(为了便于阅读,将其重新格式化为列式):

DBTIMEZONE          US/Central
SESSIONTIMEZONE     -05:00
TS                  2017-01-01 06:00:00
TS_AT_LOCAL         2017-01-01 06:00:00 -05:00
TS_AT_DB            2017-01-01 05:00:00 US/CENTRAL
TS_AT_SESSION       2017-01-01 06:00:00 -05:00

您需要知道您的时区;

SELECT myTimeStamp, from_tz(myTimeStamp, 'America/New_York') AT TIME ZONE 'UTC' utc FROM dual;

从Oracle 19c开始,引入了一个新函数TO_UTC_TIMESTAMP_TZ

SQL函数TO_UTC_TIMESTAMP_TZ将ISO 8601日期格式的字符串作为varchar输入,并返回SQL数据类型TIMESTAMP WITH TIMEZONE的实例。 它将输入标准化为UTC时间(协调世界时,以前为格林威治标准时间)。 与SQL函数TO_TIMESTAMP_TZ不同,新函数假定输入字符串使用ISO 8601日期格式,默认时区为UTC 0。

select TO_UTC_TIMESTAMP_TZ ( to_char(sysdate,'yyyy-mm-dd"T"HH:MI:SS') )  as utc 
   from dual;

 UTC
31-MAR-19 05.45.36.000000 AM +00:00

暂无
暂无

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

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