Преобразование даты LDAP в SQL (миллисекунды в наносекунды)

Я получаю дату в формате milliseconds.

i.e.: 1427342400000 is essentially 3/26/2015.

Теперь я хочу дополнительно преобразовать дату в nanoseconds и передать это значение в атрибуте accountexpires в Active Directory.

Что такое запрос для преобразования даты миллисекунд в дату наносекунд?

Любая помощь будет принята с благодарностью.


person user1565893    schedule 20.02.2015    source источник


Ответы (2)


Теперь я хочу дополнительно преобразовать дату в наносекунды

Хорошо, но конвертировать в наносекунды с каких это пор? Глядя на ваш пример, я предполагаю, что начальной точкой будет '01-JAN-1970'.

Если я хочу преобразовать дату в миллисекунды с 01-JAN-1970, я бы сделал следующее:

SQL> SELECT to_number(SYSDATE - to_date('01-JAN-1970','DD-MON-YYYY')) * (24 * 60 * 60 * 1000) milliseconds
  2  FROM dual;

        MILLISECONDS
--------------------
       1424428022000

SQL>

Теперь,

1 миллисекунда = 1000000 наносекунд

, используя эту формулу, просто умножьте ее на разницу дат.

Преобразование даты в наносекунды:

SQL> SELECT to_number(SYSDATE - to_date('01-JAN-1970','DD-MON-YYYY')) * (24 * 60 * 60 * 1000 * 1000000) nanoseconds
  2  FROM dual;

         NANOSECONDS
--------------------
 1424428111000000000

SQL>

Чтобы вернуть его в актуальное состояние:

SQL> alter session set nls_date_format='DD-MON-YYYY HH24:MI:SS';

Session altered.

SQL> SELECT TO_CHAR(to_date('1970-01-01 00','yyyy-mm-dd hh24')
  2         +
  3        (1424428111000000000 )/1000000/1000/60/60/24 , 'YYYY-MM-DD HH12:MI:SS am') nano_to_date
  4  FROM dual;

NANO_TO_DATE
----------------------
2015-02-20 10:28:31 am

SQL>

ОБНОВЛЕНИЕ относительно TIMEZONE

Лучше явно указывать часовой пояс.

Вы можете указать часовой пояс в самом литерале или указать его как UTC и преобразовать в свой local timezone.

См. этот ответ.

person Lalit Kumar B    schedule 20.02.2015
comment
Учтите, что эпоха Unix — 1970:01:01 00:00:00 UTC! Он может отличаться от вашего местного часового пояса. - person Wernfried Domscheit; 20.02.2015
comment
Да, согласен. ОП просто хотел знать, как преобразовать дату в наносекунды, поэтому я не обратил особого внимания на добавление часового пояса. Я уже отвечал на аналогичный вопрос здесь stackoverflow.com/a/26711372/3989608. В любом случае, я отредактирую свой ответ и добавлю эту ссылку - person Lalit Kumar B; 20.02.2015

Когда вы говорите, что «1427342400000 — это, по сути, 26 марта 2015 года», это выглядит как отметка времени Unix.

Согласно моим выводам, временная метка LDAP

Количество интервалов в 100 наносекунд с 1601-01-01 00:00:00 UTC.

И временная метка Unix

Количество секунд (иногда используются миллисекунды) с 1970-01-01 00:00:00 UTC.

Я предполагаю, что вы получили временную метку Unix и хотите преобразовать ее в временную метку LDAP. Эта функция должна работать:

CREATE OR REPLACE FUNCTION ConvertTime(unixTimestamp IN NUMBER) RETURN NUMBER IS
    timestampUTC TIMESTAMP;
    theInterval INTERVAL DAY(9) TO SECOND(9);
    epoche NUMBER;
BEGIN

    -- Convert Unix Timestamp-Number to TIMESTAMP:
    timestampUTC := (TIMESTAMP '1970-01-01 00:00:00' AT TIME ZONE 'UTC' + unixTimestamp * (INTERVAL '1' SECOND / 1000));

    -- Convert TIMESTAMP to LDAP Timestamp-Number 
    theInterval := timestampUTC - TIMESTAMP '1601-01-01 00:00:00' AT TIME ZONE 'UTC';
    epoche := EXTRACT(DAY FROM theInterval)*24*60*60 
        + EXTRACT(HOUR FROM theInterval)*60*60 
        + EXTRACT(MINUTE FROM theInterval)*60 
        + EXTRACT(SECOND FROM theInterval);
    RETURN ROUND(epoche * 1e9/100);

END ConvertTime;


SELECT TO_CHAR(ConvertTime(1427342400000), 'fm999999999999999999999') FROM dual;

130718108400000000

Обновление:

Вы можете сделать это намного лучше:

SELECT 
    TO_CHAR((1427342400000/1000 + (DATE '1970-01-01' - DATE '1601-01-01')*24*60*60) * (1e9/100), 'fm999999999999999999999') AS LDAP_TS
FROM dual;

130718160000000000

Однако вы получаете разницу в 5160 секунд (86 минут), но я понятия не имею, почему вы это получаете. Для интервала между двумя датами часовой пояс не должен иметь значения.

person Wernfried Domscheit    schedule 20.02.2015