sys_extract_utc和夏天/冬天的问题

时间:2017-03-24 11:39:53

标签: sql oracle timezone timezone-offset

我在将时间戳转换为UTC时遇到问题。

我们的系统时区是欧洲/柏林'。此时的实际ZoneOffset(因为它不是夏季)是+1。此ZoneOffset将于2017年3月26日从+1更改为+2。 (冬季到夏季)。

如果我使用函数sys_extract_utc('2017.03.27 00:00'),那么现在适用的偏移量将用于计算。结果是' 2017.03.26 23:00',但我期待结果' 2017.03.26 22:00'。

如何获得正确的结果?

1 个答案:

答案 0 :(得分:2)

你说

  

现在适用的偏移用于计算

这不太正确。您的会话时区似乎设置为+01:00偏移而不是区域名称:

alter session set nls_timestamp_format = 'YYYY-MM-DD HH24:MI:SS';
alter session set TIME_ZONE = '+01:00';
select sys_extract_utc(timestamp '2017-03-27 00:00:00') from dual;

SYS_EXTRACT_UTC(TIM
-------------------
2017-03-26 23:00:00

提供的时间戳文字没有时区信息,因此它作为函数调用的一部分隐式转换为会话时区。偏移量不了解夏季/冬季,因此不会(或可能)进行调整。如果你在27日之后运行该查询,你会看到同样的事情。

如果您将会话时区设置为该区域,那么您将获得正确的结果。

alter session set TIME_ZONE = 'Europe/Berlin';
select sys_extract_utc(timestamp '2017-03-27 00:00:00') from dual;

SYS_EXTRACT_UTC(TIM
-------------------
2017-03-26 22:00:00

您可以通过修改操作系统环境变量自动执行此操作;如果没有,那么您可以在.login.glogin安装文件中的客户端或(对于SQL * Plus)进行设置。

如果你从一个实际上有一个区域的值开始,即是一个带有时区数据类型的时间戳,那么会话时区并不重要:

alter session set TIME_ZONE = '+01:00';
select sys_extract_utc(timestamp '2017-03-27 00:00:00 Europe/Berlin') from dual;

SYS_EXTRACT_UTC(TIM
-------------------
2017-03-26 22:00:00