Oracle:将 DateTime 转换为 Epoch 时出错

Oracle: Error in converting DateTime to Epoch

尝试将日期时间转换为纪元时,出现错误:ORA-01810:格式代码出现两次

QracleSQL 查询:

select (trunc(TO_TIMESTAMP('2022-05-08T19:09:17Z', 'yyyy-MM-dd"T"HH:mm:ssXXX')) - TO_DATE('01/01/1970', 'MM/DD/YYYY')) * 24 * 60 * 60 from dual;

像这样:

测试数据

create table sample_inputs (ts_string) as
  select '2022-05-08T16:49:34Z'     from dual union all
  select '2022-04-15T04:20:13.525Z' from dual
;

查询和输出

with
  prep (ts_string, ts) as (
    select ts_string,
           to_timestamp(ts_string, 'yyyy-mm-dd"T"hh24:mi:ss.ff"Z"')
    from   sample_inputs
  )
select ts_string,
       round((trunc(ts, 'mi') - date '1970-01-01') * 24 * 3600)
         + extract(second from ts)
       as epoch
from   prep;

TS_STRING                        EPOCH
-------------------------- -----------
2022-05-08T16:49:34Z        1652028574
2022-04-15T04:20:13.525Z    1649996413.525

备注

在你的尝试中有几个错误。 Oracle fractional-seconds 元素是 ff,而不是 xxx。您在末尾缺少 hard-coded Z 的占位符(掩码中有“T”,这是正确的,但您缺少类似的“Z”)。 HH 是不够的 - 它必须是 HH24HH,最后是 AM(或等效的 PM)。在你的例子中,它显然是 HH24MMmm 在 Oracle 中意味着同样的事情——这不是 Unix。分钟的元素是 mi 或等效的 MI.

我写的查询在纪元中保留小数秒。今天早些时候的另一个问题(也许你也是,在另一个用户名下)被关闭为“重复” - 但声称的“重复”与保留小数秒完全无关,当输入是 Oracle 时间戳与 Oracle 日期(哪个总是有时间成分,但只有整秒)。

你应该使用:

  • TO_TIMESTAMP_TZ 而不是 TO_TIMESTAMP
  • 格式模型 YYYY-MM-DD"T"HH24:MI:SS.FF TZD 而不是错误地使用 MM 两次,HH24 而不是 HH.FF 而不是 XXX,和 TZD 而不是硬编码 "Z".
  • 确保您始终将时间戳转换为 UTC 时区(您的已经是,但其他人可能不是)
  • 不要 TRUNC在午夜将时间戳设为 DATE,否则您将丢失时间部分。

像这样:

SELECT ROUND(
         (
           TRUNC(timestamp_value AT TIME ZONE 'UTC', 'MI')
           - DATE '1970-01-01'
         ) * 86400
         + EXTRACT(SECOND FROM timestamp_value AT TIME ZONE 'UTC')
       ) AS epoch_time
FROM   (
  SELECT TO_TIMESTAMP_TZ(
           '2022-05-08T19:09:17Z',
           'YYYY-MM-DD"T"HH24:MI:SS.FF TZD'
         ) AS timestamp_value
  FROM   DUAL
);

输出:

EPOCH_TIME
1652033357

db<>fiddle here