将时间戳转换为带时区的时间戳
Cast timestamp to timestamp with time zone
我正在尝试通过添加 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 日期格式。如何指定添加时区?
您需要使用the to_timestamp_tz()
function,而不仅仅是to_timestamp
; '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
正如您所注意到的,您正在使用所选格式模型丢失小数秒。
您还可以用 the at time zone
expression:
指定一个值代表的时区
select t.time_started at time zone 'GMT' from t;
T.TIME_STARTEDATTIMEZONE'GMT'
-----------------------------------
05-JAN-15 18.12.53.419495000 GMT
或者您可以使用 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_started
的类型是TIMESTAMP
,并且请求是在给定的时区解释这个时间戳,那么这里要使用函数FROM_TZ
。
相比之下,AT TIME ZONE
子句用于将 TIMESTAMP WITH TIME ZONE
值从一个时区移动到另一个时区。
这意味着对于以下 SELECT
语句,首先将 TIMESTAMP
值隐式转换(使用当前会话时区)到 TIMESTAMP WITH TIME ZONE
值,然后进行此操作值显示在另一个时区,这可能不是预期的结果和问题的解决方案。
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 显示,但明显不同。
我正在尝试通过添加 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 日期格式。如何指定添加时区?
您需要使用the to_timestamp_tz()
function,而不仅仅是to_timestamp
; '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
正如您所注意到的,您正在使用所选格式模型丢失小数秒。
您还可以用 the at time zone
expression:
select t.time_started at time zone 'GMT' from t;
T.TIME_STARTEDATTIMEZONE'GMT'
-----------------------------------
05-JAN-15 18.12.53.419495000 GMT
或者您可以使用 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_started
的类型是TIMESTAMP
,并且请求是在给定的时区解释这个时间戳,那么这里要使用函数FROM_TZ
。
相比之下,AT TIME ZONE
子句用于将 TIMESTAMP WITH TIME ZONE
值从一个时区移动到另一个时区。
这意味着对于以下 SELECT
语句,首先将 TIMESTAMP
值隐式转换(使用当前会话时区)到 TIMESTAMP WITH TIME ZONE
值,然后进行此操作值显示在另一个时区,这可能不是预期的结果和问题的解决方案。
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 显示,但明显不同。