JavaScript Date Gotcha

Home / JavaScript Date Gotcha

Dates are pretty easy to manage with pure JavaScript. The other day though, I discovered a bug in a bit of date manipulating code.


Take this bit for example:

getMonthYears = function () {
    // Determine the max month from vm.records and go from there.
    vm.monthYears = [];
    var orderedList = $filter('orderBy')(vm.records, 'monthYear', true);
    var max = orderedList[0].monthYear;
    var split = max.split("-");
    var date = new Date(split[0], split[1], 1, 0, 0, 0, 0);
    for (var i = 0; i < 3; i++) {
        date.setMonth(date.getMonth() + 1);
        var monthYear = date.getFullYear() + "-" + ('00' + date.getMonth().toString()).slice(-2);
        vm.monthYears.push(monthYear);
    }
}

This code takes a list of months in the format “YYYY-MM,” determines the maximum month (by ordering with an Angular filter), and then generates (3) months in the future. These months are used in a UI drop-down for selecting a month. The problem that I discovered though is that months in JavaScript start at zero – not one. It seems like I knew this, but then didn’t. 🙂

The output data, then, when crossing the year boundary would look like this:

  • 2016-10
  • 2016-11
  • 2017-00

That was quite puzzling. The fix is pretty simple. Decrement the our starting point by (1) and our output month by (1):

getMonthYears = function () {
    // Determine the max month from vm.records and go from there.
    vm.monthYears = [];
    var orderedList = $filter('orderBy')(vm.records, 'monthYear', true);
    var max = orderedList[0].monthYear;
    var split = max.split("-");
    var startMonth = parseInt(split[1]) - 1;
    var date = new Date(split[0], startMonth, 1, 0, 0, 0, 0);
    for (var i = 0; i < 3; i++) {
        date.setMonth(date.getMonth() + 1);
        var monthYear = date.getFullYear() + "-" + ('00' + (date.getMonth() + 1).toString()).slice(-2);
        vm.monthYears.push(monthYear);
    }
}

At any rate, I thought it was pretty interesting since, in testing when staying within a single year, the error isn’t apparent.

The behavior can also easily be seen by initializing a date with a month of 12 and year of 2016:

var date = new Date(2016, 12, 1, 0, 0, 0, 0 ,0)
Sun Jan 01 2017 00:00:00 GMT-0500 (Eastern Standard Time)

Leave a Reply