Yesterday’s post made me want to extend the Date.prototype object a bit more. Therefore I came up with the following code:
// Date.prototype Extensions - By Chris West - MIT Licensed
(function() {
var arr = "Years|FullYear Months|Month Days|Date Hours Minutes Seconds Milliseconds".split(" ");
for(var p = Date.prototype, n, t, i = 0; t = arr[i++];) {
n = t.split("|");
(function(s, g, a) {
p[a] = function(delta, chain) {
delta = this[s](this[g]() + delta);
return chain ? this : delta;
};
})("set" + (n[1] || n[0]), "get" + (n[1] || n[0]), "add" + n[0]);
}
p.diffYears = function(d) {
return d.getFullYears() - this.getFullYears();
};
p.diffMonths = function(d) {
return (d.getFullYear() * 12 + d.getMonth())
- (this.getFullYear() * 12 + this.getMonth());
};
var intervals = [864e5,36e5,6e4,1e3,1];
for(arr.splice(0, 2), i = -1; t = arr[++i];) {
(function(d, i) {
p[d] = function(d) {
return parseInt(d.getTime() / i)
- parseInt(this.getTime() / i);
};
})("diff" + t, intervals[i]);
}
})();
The above code defines the following prototypal functions:
- Date Adders
- Date.prototype.addYears()
- Date.prototype.addMonths()
- Date.prototype.addDays()
- Date.prototype.addHours()
- Date.prototype.addMinutes()
- Date.prototype.addSeconds()
- Date.prototype.addMilliseconds()
- Date Differs
- Date.prototype.diffYears()
- Date.prototype.diffMonths()
- Date.prototype.diffDays()
- Date.prototype.diffHours()
- Date.prototype.diffMinutes()
- Date.prototype.diffSeconds()
- Date.prototype.diffMilliseconds()
Unlike the XDate code, these functions are not automatically chainable, but if the second parameter evaluates to true
it will be:
var d = new Date("2012/09/12");
alert(d); // Wed Sep 12 2012
alert(d.addDays(5, true).addYears(-1, true)); // Sat Sep 17 2011
Another difference is the fact that the diff functions only return rounded numbers, not floating-point numbers:
var d1 = new Date("1987/04/25 10:01:25");
var d2 = new Date("1987/04/25 10:03:00");
alert(d1.diffMinutes(d2)); // 2
I am not going to claim that this is equivalent to the XDate library, but on the other hand, this helps you see how little code can be written in JavaScript to get the job done. If you want the minified version (631 bytes) of this code, you can find it here. 8)
3 Comments
ildar · September 15, 2012 at 3:50 AM
It happened that I read your blog periodically 🙂 and sometimes I want to comment it.
Usage of closure is good idea to make a code shorter. However it can play the cruel joke. Look this:
new Date().addMonths(1) // works fine
new Date().addHours(1) // failed because there are setHours/getHours methods only
Consider different workarounds. For example try the code below. I am not sure that the code will be posted correctly.
var proto = Date.prototype;
var m = {
‘Years’: ‘FullYear’,
‘Months’: ‘Month’,
‘Days’: ‘Date’,
‘Hours’: ‘Hours’,
‘Minutes’: ‘Minutes’,
‘Seconds’: ‘Seconds’,
‘Milliseconds’: ‘Milliseconds’
};
for (var p in m) {
if ( ! m.hasOwnProperty(p) ) {
continue;
}
(function()
{
var q = m[p];
proto[‘add’ + p] = function(delta)
{
this[‘set’ + q](this[‘get’ + q]() + delta);
return this;
};
})();
}
May be you will be interested to exam my extension http://code.google.com/p/jsxt/source/browse/trunk/js/Date.js
I implemented there the static methods Date.moveXXX(), Date.diff(), Date.between()
Chris West · September 18, 2012 at 11:26 AM
Thanks for testing it out. I guess I made a few changes and forgot to test out the time functions again. I have slightly modified it and now everything works again. I will check out your extension code soon.
JavaScript – Date Difference Function | Chris West's Blog · December 21, 2012 at 2:47 PM
[…] few months ago I wrote a blog post about extensions to the Date.prototype. That post provided ways to add date parts and subtract date parts. Today’s post shows you […]