JavaScript – Date.prototype Extensions

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 thoughts on “JavaScript – Date.prototype Extensions”

  1. 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()

    1. 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.

Leave a Reply

Your email address will not be published. Required fields are marked *


four − = 0

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="">