【发布时间】:2020-07-06 20:53:37
【问题描述】:
我有一个 varchar 列,其值为 2020-07-05T00:00:00.000+0000,我希望在 oracle 中的 DD-MON-YYYY 中进行相同的转换,即 2020 年 7 月 5 日。
提前致谢。
【问题讨论】:
-
时间总是午夜,时区总是格林威治标准时间吗?
-
为什么将 TIMESTAMP 值存储为 字符串?
我有一个 varchar 列,其值为 2020-07-05T00:00:00.000+0000,我希望在 oracle 中的 DD-MON-YYYY 中进行相同的转换,即 2020 年 7 月 5 日。
提前致谢。
【问题讨论】:
您的日期不是日期,而是带有时区的时间戳。不要使用TO_DATE,因为您将丢弃大量信息,并且在丢弃信息时可能会得到错误的日期。请改用TO_TIMESTAMP_TZ。
SELECT TO_TIMESTAMP_TZ( your_column, 'YYYY-MM-DD"T"HH24:MI:SS.FF3TZHTZM' )
FROM your_table
如果您真的想天真地将时间戳转换为字符串并丢弃时区信息而不将其应用于日期,那么只需使用TO_CHAR:
SELECT TO_CHAR(
TO_TIMESTAMP_TZ( your_column, 'YYYY-MM-DD"T"HH24:MI:SS.FF3TZHTZM' ),
'DD-MON-YYYY',
'NLS_DATE_LANGUAGE=AMERICAN'
)
FROM your_table
但是,您可能希望标准化时区并将所有时间戳转换为公共时区(即 UTC),并且需要使用AT TIME ZONE 'UTC':
SELECT TO_CHAR(
TO_TIMESTAMP_TZ( your_column, 'YYYY-MM-DD"T"HH24:MI:SS.FF3TZHTZM' )
AT TIME ZONE 'UTC',
'DD-MON-YYYY',
'NLS_DATE_LANGUAGE=AMERICAN'
)
FROM your_table
所以,对于一些测试数据:
CREATE TABLE your_table ( your_column ) AS
SELECT '2020-07-05T00:00:00.000+0000' FROM DUAL UNION ALL
SELECT '2020-07-05T00:00:00.000+0100' FROM DUAL UNION ALL
SELECT '2020-07-04T23:00:00.000-0100' FROM DUAL;
然后上面的选项:
SELECT TO_TIMESTAMP_TZ( your_column, 'YYYY-MM-DD"T"HH24:MI:SS.FF3TZHTZM' )
AS timestamp,
TO_CHAR(
TO_TIMESTAMP_TZ( your_column, 'YYYY-MM-DD"T"HH24:MI:SS.FF3TZHTZM' ),
'DD-MON-YYYY',
'NLS_DATE_LANGUAGE=AMERICAN'
) AS ignore_timezone,
TO_CHAR(
TO_TIMESTAMP_TZ( your_column, 'YYYY-MM-DD"T"HH24:MI:SS.FF3TZHTZM' )
AT TIME ZONE 'UTC',
'DD-MON-YYYY',
'NLS_DATE_LANGUAGE=AMERICAN'
) AS utc_date
FROM your_table
将输出:
时间戳 | IGNORE_TIMEZONE | UTC_DATE :---------------------------- | :---------------- | :---------- 2020-07-05T00:00:00.000+0000 | 2020 年 7 月 5 日 | 2020 年 7 月 5 日 2020-07-05T00:00:00.000+0100 | 2020 年 7 月 5 日 | 2020 年 7 月 4 日 2020-07-04T23:00:00.000-0100 | 2020 年 7 月 4 日 | 2020 年 7 月 5 日
db小提琴here
【讨论】:
使用to_date()转换为日期:
select to_date(substr(col, 1, 10), 'YYYY-MM-DD')
我认为没有理由将其转换回字符串,但如果你真的想要,你可以使用to_char()。
Here 是一个 dbfiddle。
【讨论】: