Search code examples
javascriptdateldapdate-conversion

How to to convert from ldap time format to js date format?


I want to read a time stamp from Active Directory and compare it to an other date created in JS. From AD I'm getting the date in form of an 18-digit number (time in 100 nanoseconds since Jan 1, 1601 UTC). JavaScript uses date numbers in form of a 13-digit number (time in miliseconds since Jan 1, 1970 UTC).

Is there a convert function already implemented or how would you convert it?


Solution

  • Based on the question here*, 1.29265206716E+17 represents 2010-08-17T12:11:11Z so that can be used as a test value. The LDAP time value is in units of 0.0000001 of a second, whereas ECMAScript uses 0.001 of a second.

    So the steps are:

    1. Convert the LDAP time value to milliseconds (divide by 1e4)
    2. Get the time difference between 1601-01-01 and 1970-01-01 in milliseconds
    3. Subtract the difference
    4. Pass to the Date constructor to create a Date object

    Which can be combined into a single expression:

    function ldapToJS(n) {
    
      // Longer, equivalent to short version
      // return new Date(n/1e4 + new Date(Date.UTC(1601,0,1)).getTime());
    
      // Shorter, more efficient. Uses time value for 1601-01-01 UTC
      return new Date(n/1e4 - 1.16444736e13);
    }
    
    console.log(ldapToJS(1.29265206716E+17).toISOString()); // 2010-08-17T02:11:11.600Z
    console.log(ldapToJS(1.3160237812e17).toISOString());   // 2018-01-12T13:36:52.000Z
    
    function doConversion(){
      document.getElementById('dateString').textContent = ldapToJS(+document.getElementById('ldap').value).toISOString();
    }
    <input placeholder="LDAP time value" id="ldap">
    <button onclick="doConversion()">Convert</button>
    <br>
    <span id="dateString"></span>

    LDAP timestamps can be generated and converted to date strings at the LDAP, Active Directory & Filetime Timestamp Converter.

    * How to convert LDAP timestamp to Unix timestamp

    You could even add a static fromLDAPTV method to the built-in Date:

    // Convert LDAP time value to Date
    if (!Date.fromLDAPTV) {
      Date.fromLDAPTV = function (n) {
        return new Date(n/1e4 - 1.16444736e13);
      }
    }
    
    console.log(Date.fromLDAPTV(131602386750000000))
    
    // Convert LDAP string to date (only timezone Z)
    if (!Date.fromLDAPString) {
      Date.fromLDAPString = function (s) {
        var b = s.match(/\d\d/g);
        return new Date(Date.UTC(b[0]+b[1], b[2]-1, b[3], b[4], b[5], b[6]));
      }
    }
    
    console.log(Date.fromLDAPString('20180112232359Z'));