Oracle SQL:将时间戳转换为UTC

时间:2014-03-27 13:24:11

标签: sql oracle utc sql-timestamp

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

select myTimeStamp, MyName, MyBranch from tableA
  

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

我尝试过使用sys_extract_utc(myTimeStamp),但我有错误

  

sql命令未正确结束

myTimestamp的类型为“日期”。

4 个答案:

答案 0 :(得分:17)

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

因为mytimestamp实际上是date而不是您需要投射它的时间戳。这样做会使Oracle认为存储在mytimestamp中的信息位于服务器的时区 - 如果您不需要使用Madhawas'溶液

答案 1 :(得分:9)

根据类型的不同,有几个关于Oracle转换的时区的问题取决于myTimestamp的数据类型。

带时区的时间戳

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

带有本地时区的时间戳

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

时间戳

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

  • 对此的显式调用是myTimestamp at local
  • 或者(很可能更好),你可以像 Madhawas 那样说,并使用from_tz函数显式构建一个具有除会话之外的显式时区的值。

日期

如上所述,尝试执行上述任何操作日期将会失败:

  • myTimestamp at time zone 'UTC'
    ORA-30084:带有时区修改符的日期时间主数据的无效数据类型

  • from_tz(myTimestamp, 'America/New_York')
    ORA-00932:不一致的数据类型:预期的TIMESTAMP得到日期

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

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

示例脚本

以下脚本说明了该行为。请注意,在我的系统上,dbtimezone是US / Central,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

答案 2 :(得分:5)

你需要知道你的时区;

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

答案 3 :(得分:0)

从Oracle 19c开始,引入了一个新功能,即TO_UTC_TIMESTAMP_TZ

  

SQL函数TO_UTC_TIMESTAMP_TZ采用ISO 8601日期格式   字符串作为varchar输入,并返回SQL数据类型的实例   与时区的时间戳。它将输入标准化为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