Wednesday, 4 May 2016

Converting SAS Date to Javascript Date (in Javascript)

This isn't hard to figure out, but is one of those things that just should be easy to google for!

  var dtSAS=20563;
  var dtJS=new Date(+new Date(1960,0,1) + dtSAS * 86400000);
  alert(dtJS.toUTCString());

Right, that should get rid of 95% of readers, for the rest of you, a quick explanation.

First, it's important to note that SAS dates are stored as number of days since Jan 1st, 1960 - whereas Javascript "dates" are actually the number of milliseconds since Jan 1st 1970.  This explains the 86400000 value (24 days * 60 minutes * 60 seconds * 1000 milliseconds), and why the embedded Date() object is set to 1960.

Next, there's the "+" sign before that nested Date object.  That tells Javascript to return a numeric value (-315619200000) instead of a formatted value (Fri Jan 01 1960 00:00:00 GMT+0000 (GMT Standard Time)).

Finally, the .toUTCString() method avoids contention with local time conventions (eg the extra 1 hour in BST).

To make this even easier to deal with, I've knocked together a simple Javascript function - see fiddle.

// valid in ECMASCRIPT 2016
function dtSAStoJS(dtSAS,dtType='DATE'){
  // accepts SAS unformatted DATE or DATETIME
  // dtType should be used to determine the above
  // -315619200000 is equivalent to +new Date(1960,0,1)
  // 86400000 is equivalent to 24h * 60m * 60s * 1000ms
  if(dtType==='DATE'){
    return new Date(-315619200000 + dtSAS * 86400000);
  } else if (dtType==='DATETIME'){
    return new Date(-315619200000 + dtSAS * 1000);
  } else {
    console.log('Unknown dtType value - ' + dtType);
    return null;
  }
};
alert(dtSAStoJS(20578,'DATE').toUTCString());
alert(dtSAStoJS(1776743820,'DATETIME').toUTCString());

And in case you were wondering - datetime 1776743820 (GMT) was when Dr Goodnight officially announced SAS Viya!