我们如何在 oracle SQL 中将“Mon Dec 21 00:00:00 EST 2020”转换为 dd/mm/yyyy?日期存储在数据类型 NVARCHAR2 中。
答案 0 :(得分:0)
这里是如何接受输入为 nvarchar2
并将输出作为 varchar2
(如果出于某种原因需要,您可以将其转换为 nvarchar2
- 看看如何我这样做是为了输入)。
在大多数情况下,您只需要带时区的时间戳来进行进一步计算 - 转换回字符串应该只是最后一步,当您为人类可读的报告准备结果时。如果您在进一步的计算中需要“结果”,只需去掉对 to_char
的外部调用。
第三行代码显示了输入。我没有您的数据,所以我从头开始创建它 - 它是一个 nvarchar2
字符串,表示带时区的时间戳,采用您向我们展示的格式。请注意对 to_timestamp_tz
的调用中语言 的规范;如果没有它,如果您的默认值不是英语,则“Mon”和“Dec”将导致抛出错误。
select to_char(
to_timestamp_tz(
to_nchar('Mon Dec 21 00:00:00 EST 2020'),
'Dy Mon dd hh24:mi:ss TZR yyyy',
'nls_date_language = english'),
'dd/mm/yyyy') as result
from dual
;
RESULT
----------
21/12/2020
编辑
在进一步的评论中,OP 询问了不同的输入字符串,其中包含 'EDT'
作为时区组件。
这是个问题。 EST 没有歧义,但 EDT 是,因为不同的时区区域使用 EDT 夏令时标记,并且它们不会每年都在同一时间更改为夏令时。与 EST 不同,EDT必须出现在输入中,并带有实际时区区域名称; EDT 真的不是时区区域,它只是不同区域的夏令时标记,它本身并不能用来识别正确的区域。
OP 声明所有输入都应该在 'America/New_York'
区域中。如果是这样,那么可以将其添加(连接)到输入中,并且可以更改格式模型以添加 TZR
元素,如下所示。我只展示了我们将字符串转换为带时区的时间戳的部分;其余的不需要改变。
注意 - 查询结果中的 ts
的数据类型为 timestamp with time zone
;它在输出中看起来像字符串(以特定格式),因为输出总是显示字符串,但实际上结果是用于进一步处理的正确数据类型,如果需要的话 - 例如,如果必须只选择时间戳是 2021 年等。特别是,可以将 to_char
应用于结果,使用 `dd/mm/yyyy' 格式模型,以匹配 OP 的原始请求。
with
inputs (ts) as (
select 'Mon Dec 21 00:00:00 EST 2020' from dual union all
select 'Thu Mar 18 00:00:00 EDT 2021' from dual
)
select to_timestamp_tz(ts || ' America/New_York',
'Dy Mon dd hh24:mi:ss TZD yyyy TZR',
'nls_date_language = english') as ts
from inputs
;
TS
--------------------------------------------
2020-12-21 00:00:00.000 America/New_York EST
2021-03-18 00:00:00.000 America/New_York EDT