Rails-like Javascript Date Helpers

Vote on HN

I'm a fan of ActiveSupport::CoreExtensions::Time::Calculations. It gives you easy to use methods like beginning_of_day, end_of_day, beginning_of_week, end_of_day, etc. These methods make date handling code more concise and more readable. I wanted the same benefits in Javascript, so I've ported over a subset of these methods and mixed them into Javascript's Date object. Read on for the code.

Here are a few examples of what you can do with these date extensions:

// Mon Jan 12 2009 13:30:00 GMT-0800 (PST)
var monday = new Date(2009, 0, 12, 13, 30, 0);

// Wed Jan 14 2009 13:30:00 GMT-0800 (PST)
var wednesday = new Date(2009, 0, 14, 13, 30, 0);

// Fri Jan 16 2009 13:30:00 GMT-0800 (PST)
var friday = new Date(2009, 0, 16, 13, 30, 0);

wednesday.between(monday, friday);  // true

wednesday.beginningOfDay(); // Wed Jan 14 2009 00:00:00 GMT-0800 (PST)
wednesday.endOfDay(); // Wed Jan 14 2009 23:59:59 GMT-0800 (PST)

wednesday.beginningOfWeek(); // Sun Jan 11 2009 00:00:00 GMT-0800 (PST)
wednesday.endOfWeek(); // Sat Jan 17 2009 23:59:59 GMT-0800 (PST)

wednesday.beginningOfMont(); // Thu Jan 01 2009 00:00:00 GMT-0800 (PST)
wednesday.endOfMonth(); // Sat Jan 31 2009 23:59:59 GMT-0800 (PST)

Here's the code:

Date.prototype.between = function(start, end) {
  return (start <= this) && (end >= this);
};

Date.prototype.beginningOfDay = function() {
  var newDate = new Date(this);
  newDate.setHours(0);
  newDate.setMinutes(0);
  newDate.setSeconds(0);
  return newDate;
};

Date.prototype.endOfDay = function() {
  var newDate = new Date(this);
  newDate.setHours(23);
  newDate.setMinutes(59);
  newDate.setSeconds(59);
  return newDate;
};

Date.prototype.beginningOfWeek = function() {
  var newDate = new Date(this);
  var offsetToBeginning = newDate.getDay();
  newDate.setDate(newDate.getDate() - offsetToBeginning);
  return newDate.beginningOfDay();
};

Date.prototype.endOfWeek = function() {
  var newDate = new Date(this);
  // Saturday = 6
  var offsetToEnd = (6 - newDate.getDay());
  newDate.setDate(newDate.getDate() + offsetToEnd);
  return newDate.endOfDay();
};

// 0 = january, 1 = feb, ...
// does not account for leap years
Date.DAYS_OF_MONTH_MAP = [
  31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
];

Date.prototype.daysInMonth = function() {
  return Date.DAYS_OF_MONTH_MAP[this.getMonth()];
}

Date.prototype.beginningOfMonth = function() {
  var newDate = new Date(this);
  newDate.setDate(1);
  return newDate.beginningOfDay();
};

Date.prototype.endOfMonth = function() {
  var newDate = new Date(this);
  newDate.setDate(newDate.daysInMonth());
  return newDate.endOfDay();
};

I did not need every method that ActiveSupport provided, so I stuck with implementing only the ones I needed. It's pretty straightforward to write the rest of the methods if they're needed.

comments powered by Disqus