在SQL中转换LDAP日期(毫秒到纳秒)

时间:2015-02-20 02:34:02

标签: sql oracle oracle11g date-arithmetic

我以milliseconds格式收到日期。

即:1427342400000 is essentially 3/26/2015

现在我想进一步转换nanoseconds中的日期,并在Active Directory中的accountexpires属性中传递此值。

将毫秒日期转换为纳秒日期的查询是什么?

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:2)

  

现在我想以纳秒为单位进一步转换日期

好的,但从什么时候开始转换为纳秒?看一下你的例子,我认为起点是'01-JAN-1970'

如果我想将日期转换为毫秒,那么我会这样做:

01-JAN-1970

现在,

  

1毫秒= 1000000纳秒

,使用此公式,只需将其乘以日期差

将日期转换为纳秒:

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

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

SQL>

要将其转换回日期:

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

请参阅此answer

答案 1 :(得分:0)

当您说“1427342400000实际上是3/26/2015”时,它看起来像是Unix时间戳。

根据我的发现,LDAP时间戳是

1601-01-01 00:00:00 UTC以来的100纳秒间隔数。

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分钟)的差异,但我不知道你为什么会这样做。对于2个日期之间的时间间隔,时区应该没有影响。