Oracle 将时间戳转换为带时区的时间戳

Oracle 将时间戳转换为带时区的时间戳,oracle,oracle11g,Oracle,Oracle11g,我正在尝试通过添加GMT时区将时间戳转换为带时区的时间戳: to_timestamp(to_char(t.time_started, 'DD-MON-YYYY hh24:mi:ss') || nvl2(t.time_started, ' GMT', null), ('DD-MON-YYYY hh24:mi:ss tzd')) 但这会导致ORA-01812日期格式无法识别。如何指定添加时区?您需要使用,而不仅仅是添加时间戳;“tzd”格式元素无法识别,因此您的错误: select to_ti

我正在尝试通过添加GMT时区将时间戳转换为带时区的时间戳:

to_timestamp(to_char(t.time_started, 'DD-MON-YYYY hh24:mi:ss')
  || nvl2(t.time_started, ' GMT', null), ('DD-MON-YYYY hh24:mi:ss tzd'))
但这会导致ORA-01812日期格式无法识别。如何指定添加时区?

您需要使用,而不仅仅是添加时间戳;“tzd”格式元素无法识别,因此您的错误:

select to_timestamp_tz(to_char(t.time_started, 'DD-MON-YYYY hh24:mi:ss')
  || nvl2(t.time_started, ' GMT', null), ('DD-MON-YYYY hh24:mi:ss tzd'))
from t;

TO_TIMESTAMP_TZ(TO_CHAR(T.TIME_STARTED,'DD-MON-YYYYHH24:MI:SS')||NVL2(T.TIME_STARTED,'GMT',NULL),('DD-MON-YYYYHH24:MI:SSTZD'))
------------------------------------------------------------------------------------------------------------------------------
05-JAN-15 18.09.28.000000000 EUROPE/LONDON                                                                                     
正如您所注意到的,您所选择的格式模型正在丢失分数秒

您还可以指定值表示的时区:

或者您可以使用cast,正如您的问题标题所建议的,我相信它假设系统时区:

select cast(t.time_started as timestamp with time zone) from t;

CAST(T.TIME_STARTEDASTIMESTAMPWITHTIMEZONE)
-------------------------------------------
05-JAN-15 18.14.19.236338000 EUROPE/LONDON  
我在英国,所以这对我来说很有效,但是如果您的服务器位于不同的时区,那么您可能需要转换它。

如果t.time\u start列是TIMESTAMP类型的,并且请求在给定的时区中解释此时间戳,那么这里将使用来自\u TZ的函数

相反,AT TIME ZONE子句用于将具有时区值的时间戳从一个时区移动到另一个时区

这意味着,使用下面的SELECT语句,首先将使用时间戳值的当前会话时区隐式转换为具有时区值的时间戳,然后将该值显示在另一个时区中,这可能不是预期的结果和问题的解决方案

select t.time_started at time zone 'GMT' from t
请参见下面的示例,其中显示了差异。我的会话时区当前为+2:00

CREATE TABLE t
(
   time_started    TIMESTAMP
);

INSERT INTO t
     VALUES (CURRENT_TIMESTAMP);

SELECT * FROM t;


SELECT FROM_TZ(t.time_started, 'GMT') as T1, t.time_started AT TIME ZONE 'GMT' as T2 FROM t
结果是:

+-----------------------------------+-----------------------------------+
|                T1                 |                T2                 |
+-----------------------------------+-----------------------------------+
| 2019-07-16 12:17:29,068660 +00:00 | 2019-07-16 10:17:29,068660 +00:00 |
+-----------------------------------+-----------------------------------+

这两个值都以GMT显示,但明显不同。

除非有非常特殊的需要,否则使用AT TIME ZONE子句是明确的方法;从OP的原始查询和标题中,仅涵盖基础。似乎我应该更强调时区选项。
+-----------------------------------+-----------------------------------+
|                T1                 |                T2                 |
+-----------------------------------+-----------------------------------+
| 2019-07-16 12:17:29,068660 +00:00 | 2019-07-16 10:17:29,068660 +00:00 |
+-----------------------------------+-----------------------------------+