What is equivalent of DateTime.ToOADate() in javascript?
How can I get the OADate (OLE Automation date) in javas开发者_开发技巧cript? 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?
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
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)
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));
},
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;
};
})();
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;
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;
}
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#.
精彩评论