Mo Valipour
Mo Valipour

Reputation: 13496

What is equivalent of DateTime.ToOADate() in javascript?

How can I get the OADate (OLE Automation date) in javascript? I need to pass my date object (to my web service) in the form of a double value.

in c#:

var d = DateTime.Now.ToOADate();

what is the equivalent in js?

Upvotes: 5

Views: 10169

Answers (8)

Md Shahriar
Md Shahriar

Reputation: 2786

function toOLE(date) {

    const originUTC = new Date("1899-12-30T00:00:00Z").getTime();

    return (date.getTime() - originUTC) / (24 * 60 * 60 * 1000);
}

toOLE(new Date("2024-04-12T15:20:39Z"))  // Output : 45394.639340277776


function fromOLE(oleFloat) {

    const originUTC = new Date("1899-12-30T00:00:00Z").getTime();

    return new Date(originUTC + oleFloat * (24 * 60 * 60 * 1000));
}

const d = fromOLE(45394.639340277776);

console.log(d.toISOString());   //  Output : 2024-04-12T15:20:39.000Z

Upvotes: 0

Doron Saar
Doron Saar

Reputation: 486

with time zone offset repair:

function toOADate(date) {
    var msPerDay = 24 * 60 * 60 * 1000;
    var baseDate = new Date("1899-12-30T00:00:00.000+0000");
    return (date.getTime() - baseDate.getTime() - 60*1000*getTimezoneOffset()) / msPerDay;
}

Upvotes: 0

carson
carson

Reputation: 193

markitondemand@Github solved it in the following way and it accounts for DST

https://github.com/markitondemand/moment-msdate/blob/master/moment-msdate.js

toOADate: function (date) {
    var timezoneOffset = date.getTimezoneOffset() / (60 * 24);
    var msDateObj = (date.getTime() / 86400000) + (25569 - timezoneOffset);
    return msDateObj;
 },
fromOADate: function (oadate) {
   var date = new Date(((oadate - 25569) * 86400000));
   var tz = date.getTimezoneOffset();
   return new Date(((oadate - 25569 + (tz / (60 * 24))) * 86400000));
},

Upvotes: 4

Dave Strickler
Dave Strickler

Reputation: 161

Those look good for JS above, but if you want to do convert it into a Unix timestamp in PHP, use the following:

// $ms_date_floating_point is the MS date
// 42372.3432210648 converts to Sun Jan 3rd, 2016
$ms_date_seconds = $ms_date_floating_point * 60 * 60 * 24;
$unix_timestamp_seconds = strtotime("Nov 11, 1899 00:00:00") + $ms_date_seconds;

Upvotes: 0

daniel.gindi
daniel.gindi

Reputation: 3496

A solution that works for DST dates as well:

var toOADate = (function () {
    /** @const */ var utc18991230 = Date.UTC(1899, 11, 31);
    /** @const */ var msPerDay = 24 * 60 * 60 * 1000;

    return function (date) {
        if (date instanceof Date) {
            date = Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());
        }
        return (date - utc18991230) / msPerDay;
    };

})();

Upvotes: 1

Eric Lippert
Eric Lippert

Reputation: 660445

To convert a JScript date to an OLE Automation date, call getVarDate:

http://msdn.microsoft.com/en-us/library/4d4x3w61(VS.85).aspx

(If you go the other way -- that is, you have a JScript object and you assign a property containing a variant of VT_DATE type -- the JScript engine should automatically convert that to the equivalent JScript date.)

If your browser provider did not do you the courtesy of writing a getVarDate method, well, it is not difficult to write the code yourself, but in order to get it right for all cases you have to handle some tricky special cases involving dates before the epoch.

The best way I know of to get the code right is to first convert it to the raw number of whole and fractional days since the epoch, which I note is midnight of December 30, not 31, 1899. Once you have that, you can special-case the before-epoch values.

Be very careful about rounding! I recommend that you round values off to the nearest second before you do the conversion to the OA format. Because the OA format is one where -1.9999999 is just before midnight December 30th 1899, but -2.0 is midnight December 28th, if you round the former to the latter, you just rounded a fraction of a second off into a two-day error.

For the details on the quirks of the OA format, see my article from 2003 on the subject:

http://blogs.msdn.com/b/ericlippert/archive/2003/09/16/53013.aspx

And for an entertaining look at the deeper history of this odd date format, see Joel's article about his Microsoft days:

http://www.joelonsoftware.com/items/2006/06/16.html

Upvotes: 9

SLaks
SLaks

Reputation: 888017

If you can't modify the web service, you'll have to re-implement ToOADate().

MSDN says,

An OLE Automation date is implemented as a floating-point number whose integral component is the number of days before or after midnight, 30 December 1899, and whose fractional component represents the time on that day divided by 24. For example, midnight, 31 December 1899 is represented by 1.0; 6 A.M., 1 January 1900 is represented by 2.25; midnight, 29 December 1899 is represented by -1.0; and 6 A.M., 29 December 1899 is represented by -1.25.

Thus, you should be able to write something like

var oaDate = (date - new Date(1899, 11, 31)) / (24 * 60 * 60 * 1000);

(untested)

Upvotes: 5

SLaks
SLaks

Reputation: 888017

You should change your webservice to take a UNIX timestamp.

You can then call new Date().getTime() in Javascript, or (someDate - new DateTime(1970, 1, 1)).TotalMilliseconds in C#.

Upvotes: -1

Related Questions