2013-10-24 7 views
1

Я новичок в PL/SQL, которому нужно перевести миллисекунды с момента unix до даты/времени. Я могу конвертировать в GMT время/время, но не знаю, как настроить для часового пояса. Я рядом, но не совсем там.Oracle: эпоха миллисекунд на дату/время с включенным часовым поясом

Мой вход 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 (ДАТА '1970-01-01' + (1/24/60/60/1000) * r_msg.OriginationTime AS TIMESTAMP), 'Америка/New_York'), ' MM/DD/ГГГГ HH24: MI: SS ');

TMPorig2: = TO_CHAR ( FROM_TZ (CAST (ДАТА '1970-01-01' + (1/24/60/60/1000) * r_msg.OriginationTime AS TIMESTAMP), 'Тихий океан/Pago_Pago'), ' MM/DD/ГГГГ HH24: MI: SS ');

Второе решение

TMPorig: = TO_CHAR ( ДАТА '1970-01-01' + (1/24/60/60/1000) * r_msg.OriginationTime + Interval '-04: 00' ЧАС В МИНУТ, «MM/DD/ГГГГ 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/ГГГГ HH24: MI: SS ');


+0

Хорошо, я отредактировал мой ответ - проверить новое решение. –

ответ

1

Edit: Хорошо, попробуйте это решение вместо:

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; 

Выход:

VAL    
------------------- 
10/23/2013 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; 

Выход:

VAL    
------------------- 
10/23/2013 14:15:00
+0

это отлично работает для меня - у вас есть какой-то код, который идет в другую сторону, от строки до нескольких секунд после эпохи? – dldnh

+0

@ dldnh Не могли бы вы предоставить образцы данных и какой результат вы ожидаете? –