Oracle SQL:将时间戳转换为UTC

Fea*_*hal 13 sql oracle utc sql-timestamp

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

select myTimeStamp, MyName, MyBranch from tableA
Run Code Online (Sandbox Code Playgroud)

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

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

sql命令未正确结束

该列myTimestamp的类型为"日期".

a_h*_*ame 17

select cast(mytimestamp as timestamp) at time zone 'UTC', 
       MyName, 
       MyBranch 
from tableA
Run Code Online (Sandbox Code Playgroud)

因为mytimestamp事实上它date不是你需要投射的时间戳.这样做会使Oracle认为存储的信息位于mytimestamp服务器的时区 - 如果不是您需要使用Madhawas的解决方案.


Chr*_*lly 9

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

带时区的时间戳

它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:带有时区修改器的datetime primary的无效数据类型

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

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

select from_tz(cast(myTimestamp as timestamp), 'America/New_York') from tableA
Run Code Online (Sandbox Code Playgroud)

示例脚本

以下脚本说明了该行为.请注意,在我的系统上,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
/
Run Code Online (Sandbox Code Playgroud)

我的系统输出如下(为了便于阅读,重新格式化为柱状):

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
Run Code Online (Sandbox Code Playgroud)


Mad*_*was 5

你需要知道你的时区;

SELECT myTimeStamp, from_tz(myTimeStamp, 'America/New_York') AT TIME ZONE 'UTC' utc FROM dual;
Run Code Online (Sandbox Code Playgroud)