【问题标题】:Oracle: epoch milleseconds to date/time with time zone includedOracle:包含时区的日期/时间的纪元毫秒
【发布时间】:2013-11-03 07:40:46
【问题描述】:

我是一个 PL/SQL 新手,需要将自 unix 纪元以来的毫秒转换为 日期/时间。我可以转换为 GMT 日期/时间,但不知道如何调整 为时区。我很近,但不完全在那里。

我的输入是 r_msg.OriginationTime,它的值类似于 1382552100277

这个

MpD NUMBER        := (1/24/60/60/1000);        -- Milleseconds per Day

DFmt24 VARCHAR2(21) := 'MM/DD/YYYY HH24:MI:SS';    -- Date format

TMPorig24        VARCHAR2(20);

. . .

TMPorig24 := TO_CHAR( DATE '1970-01-01' + MpD * r_msg.OriginationTime, DFmt24);

给出类似的东西

10/23/2013 18:15:00

这正是我想要的,除了它是 GMT。

这个

    TimeZoneOffset VARCHAR(7);

    . . . 

    TimeZoneOffset := tz_offset('America/New_York' );

给予

-04:00

所以我只需要做类似的事情

TMPorig24 := TMPorig24 + TimeZoneOffset;

但我明白了

ORA-06502: PL/SQL: numeric or value error: character to number conversion error

我尝试了几种变体,但没有任何效果。

任何帮助表示赞赏。


谢谢,但我在使用这两种解决方案时遇到了问题。

无论时区如何,第一个解决方案都会打印相同的时间。 例如,这些打印相同的值。

TMPorig := TO_CHAR( FROM_TZ(CAST(DATE '1970-01-01' + (1/24/60/60/1000) * r_msg.OriginationTime AS TIMESTAMP), 'America/New_York'), 'MM/DD/YYYY HH24:MI:SS ');

TMPorig2 := TO_CHAR( FROM_TZ(CAST(DATE '1970-01-01' + (1/24/60/60/1000) * r_msg.OriginationTime AS TIMESTAMP), 'Pacific/Pago_Pago'), 'MM/DD/YYYY HH24:MI:SS ');

第二种方案

TMPorig := TO_CHAR( DATE '1970-01-01' + (1/24/60/60/1000) * r_msg.OriginationTime + INTERVAL '-04:00' HOUR TO MINUTE, 'MM/DD/YYYY HH24:MI:SS');

给予

PLS-00166: bad format for date, time, timestamp or interval literal

Moveover, '04:00' 将在夏令时结束时出错。 我需要 EST/EDT 和 GMT 之间时差的表达式。

********* 非常感谢**************

TMPorig2 := TO_CHAR ( FROM_TZ ( CAST (DATE '1970-01-01' + (1/24/60/60/1000) * r_msg.OriginationTime AS TIMESTAMP), 'UTC') AT TIME ZONE 'America/New_York', 'MM/DD/YYYY HH24:MI:SS');


【问题讨论】:

  • 好的,我已经编辑了我的答案 - 检查新的解决方案。

标签: oracle date time epoch zone


【解决方案1】:

编辑:好的,试试这个解决方案:

SELECT
  TO_CHAR (
    FROM_TZ (
      CAST (DATE '1970-01-01' + (1/24/60/60/1000) * 1382552100277 AS TIMESTAMP),
      'UTC')
    AT TIME ZONE 'America/New_York',
  'MM/DD/YYYY HH24:MI:SS') val
FROM dual;

输出:

值
------------------
2013 年 10 月 23 日 14:15:00 

您必须将DATE 转换为TIMESTAMP 并使用FROM_TZ 函数将TIMESTAMP 转换为TIMESTAMP WITH TIME ZONE 数据类型。时区参数可以是任一格式:America/New_York-04:00

SELECT
  TO_CHAR(
    FROM_TZ(
      CAST(DATE '1970-01-01' + (1/24/60/60/1000) * 1382552100277 AS TIMESTAMP),
      'America/New_York'),
    'MM/DD/YYYY HH24:MI:SS')
FROM dual;

如果你想要一个TIMESTAMP WITH TIME ZONE 变量。如果要添加给定时区的偏移量,则可以使用:

SELECT
  TO_CHAR(
      DATE '1970-01-01' + (1/24/60/60/1000) * 1382552100277 + INTERVAL '-04:00' HOUR TO MINUTE,
    'MM/DD/YYYY HH24:MI:SS') AS val
FROM dual;

输出:

值
------------------
2013 年 10 月 23 日 14:15:00 

【讨论】:

  • 这对我来说非常有用 - 你是否碰巧有一些相反的代码,从字符串到纪元后几秒?
  • @dldnh 您能否提供示例数据以及您期望的输出?
猜你喜欢
  • 2023-03-27
  • 2014-03-14
  • 1970-01-01
  • 1970-01-01
  • 2020-08-27
  • 2016-04-17
  • 2020-12-04
  • 2021-04-01
  • 1970-01-01
相关资源
最近更新 更多