如何将“21-05-26 12:26:00.824000000 AMERICA/TORONTO”转换为“2021-05-26T12:26:00.824Z”格式?

时间:2021-05-31 22:10:32

标签: sql oracle datetime

我已经尝试过这样但它不起作用。

with
  inputs (ts) as (
    select '21-05-26 12:26:00.824000000 AMERICA/TORONTO' from dual 
  )
select to_timestamp_tz(ts,
                       'Dy Mon dd hh24:mi:ss TZD yyyy TZR',
                       'nls_date_language = english') as ts
from   inputs
;

2 个答案:

答案 0 :(得分:2)

您可以将输入字符串转换为带有时区值的时间戳:

select to_timestamp_tz(ts, 'RR-MM-DD HH24:MI:SS.FF TZR') as ts from inputs

由于您的输入字符串只有两位年份,您可以使用 YY or RR;后者往往是合适的,但它取决于您的数据。理想情况下,您应该有 4 位数的年份来避免这个问题。您无需在此处指定语言,因为您没有任何日期或月份名称;它没有伤害,但没有做任何事情。时区名称不依赖于 NLS。

然后您的客户端或应用程序将格式化显示,通常使用会话 NLS_TIMESTAMP_TZ_FORMAT 设置。如果您想要该特定格式的字符串结果,您可以使用以下命令显式转换回字符串:

select to_char(
  to_timestamp_tz(ts, 'RR-MM-DD HH24:MI:SS.FF TZR'),
  'YYYY-MM-DD"T"HH24:MI:SS.FF3"Z"') as ts
from inputs ;

2021-05-26T12:26:00.824Z

"T""Z" 部分是 character literals

但是,'Z' 表示 UTC 时间,所以也许您应该使用 at UTC 将多伦多时间转换为 UTC:

select to_char(
  to_timestamp_tz(ts, 'RR-MM-DD HH24:MI:SS.FF TZR') at time zone 'UTC',
  'YYYY-MM-DD"T"HH24:MI:SS.FF3"Z"') as ts
from inputs ;

2021-05-26T16:26:00.824Z

db<>fiddle

但是你应该只转换成一个字符串来显示;如果您要存储该值,则应将其保存为适当的时间戳、带时区的时间戳或带本地时区的时间戳。

答案 1 :(得分:0)

我不确定您到底想要什么:您的主题标题说的是转换为格式化字符串,但在主题正文中,您询问的是转换为时间戳... 所以我展示了两者:

with inputs (ts) as ( select '21-05-26 12:26:00.824000000 AMERICA/TORONTO' from dual ) 
select 
  v.*,
  to_char((string_to_timestamp at time zone 'UTC'),'yyyy-mm-dd"T"hh24:mi:ssxff3"Z"') timestamp_to_char_UTC
from (
select 
  ts, -- < string
  to_timestamp_tz(ts, 'yy-mm-dd hh24:mi:ssxff TZR', 'nls_date_language = english') as string_to_timestamp
from inputs 
) v;

TS                                          STRING_TO_TIMESTAMP                            TIMESTAMP_TO_CHAR_UTC
------------------------------------------- ---------------------------------------------- -------------------------
21-05-26 12:26:00.824000000 AMERICA/TORONTO 2021-05-26 12:26:00.824000000 AMERICA/TORONTO  2021-05-26T16:26:00.824Z