Applications, particularly business applications, require additional methods for date manipulation than provided with the Date object. Here is a script to add 21 useful methods to the Date object constructor. Every date object you create will inherit them.

The syntax for greating the methods is: Date.prototype.method_name = function () {[code];};

And, the methods are call like this: date_object.method_name().

Easy implementation and usage is what makes these worth while. Just add the download JavaScript file to your page and they are available for every date. Here is a list of the methods


  Try the methods out!.

Enter dates below and then click a method in which you are interested. An alert box will display the result. For some methods, additional information should be entered in the associated field. An explanation follows the demonstration.

Dates
Start Date
End Date
Methods (Using Start Date)
Date Names
Add to Start Date
Methods to Determine Number of Days between Two Dates
Today and End Date  
Start and End Dates  

Age DOB:

download   The Code

This code takes advantage of JavaScript's object oriented architecture. Any object can be extended by assigning new properties and methods to the prototype property of the object's constructor. Properties and methods of the prototype property are shared by all instances of the object and not copied into each instance.

The first lines in the script add four constants to date objects. There are two arrays: one for the day names and one for month names. And there are two numeric constants: one having the milliseconds in a minute and the other holding the milliseconds in a day.

    Date.prototype.DAYNAMES = ["Sunday", "Monday", "Tuesday", "Wednesday",
                               "Thursday", "Friday", "Saturday"];
    Date.prototype.MONTHNAMES = ["January", "February", "March", "April",
                                 "May", "June", "July", "August",
                                 "September", "October", "November", "December"];
    Date.prototype.msPERMIN = 1000 * 60;
    Date.prototype.msPERDAY = 1000 * 60 * 60 * 24;

The properties in the prototype are accessible within each instance of a date using the key word this. And, accessible outside the instance with dot notation as objectInstance.msPERMIN.

The methods can be divided into three groups and one odd method. Copy is the odd method. The others get information about the date, add to the date, or get an interval between dates.

  Copying Dates

Copy: (not demonstrated) Makes a copy of the date. The need for this method may not be apparent, but it has to do with how Javascript handles assignment and passing of objects. Objects are assigned (or passed) by reference: a pointer to the original object is assigned. Only primative date types (string, number, boolean) are assigned by value. To copy a date, it first must be converted to a primative value, which is used as an agrument to the date constructor, and a new date instance created.

Method definition for copy

        Date.prototype.copy = function () {
            return new Date(this.getTime());
        };

Usage:
var old_date = new Date(); var new_copy = old_date.copy();

When a date object is assigned to another variable any changes made to the date referenced by the variable are reflected in the original date, because they are really the same date object. Copy, on the other hand creates a new date object passing the value of the original. Changes only affect one date object.

  Date Information

There are eight methods to retrieve information about a date. These are: getCDay, getDayName, getCMonth, getMonthName, getDayOfYear, and lastday.

getCDay: get three letter day abbreviation for a date.

Date.prototype.getCDay = function() {
        return this.getDayName().slice(0, 3);
    };

Usage:
var date = new Date(); var day_abbrev = date.getCDay();

getDayName: get full day name for a date.

Date.prototype.getDayName = function() {
        return this.DAYNAMES[this.getDay()];
    };

Usage:
var date = new Date(); var string_day = date.getDayName();

getCMonth: get three letter month abbreviation for a date.

Date.prototype.getCMonth = function() {
        return this.getMonthName().slice(0, 3);
    };

Usage:
var date = new Date(); var month_abbrev = date.getCMonth();

getMonthName: get full month name for a date.

Date.prototype.getMonthName = function() {
        return this.MONTHNAMES[this.getMonth()];
    };

Usage:
var date = new Date(); var string_month = date.getMonthName();

getDayOfYear: get the day of year for a date (1 through 365).

Date.prototype.getDayOfYear = function() {
        var start = new Date(this.getFullYear(), 0, 0);
        return this.getDaysBetween(start) * -1;
    };

Usage:
var date = new Date(); var day = date.getDayOfYear();

lastday: get number of days in month for a date.

Date.prototype.lastday = function() {
    var d = new Date(this.getFullYear(), this.getMonth() + 1, 0);
    return d.getDate();
};

Usage:
var date = new Date(); var num_days = date.lastday();

For the most part, these are not very remarkable functions, but they can be convenient. Little explanation is needed except to point out the use of the key word this in the method and that an anonymous function is used to assign the script to a property of the Date constructor's prototype. This allows the usage of date.method() syntax for all dates.

lastday is interesting because it sets a date to the last day of a month by initializing it to the zero ( 0 ) day of the following month. Since zero is one day before the 1st, JavaScript returns the date that is 1 day before the 1st or the last day of the previous month.

JavaScript provides methods to convert a date to a time string, but the format is based on the client settings. Sometimes a specific format is required. to12HourString and to24HourString are for those occasions.

to12HourString: get time in 12 hour format (hh:mm:ss am/pm).

Date.prototype.to12HourString() {
        var h = this.getHours();
        var m = "0" + this.getMinutes();
        var s = "0" + this.getSeconds();
        var ap;

        if (h >= 12) {
            ap = "pm";
            if (h >= 13) h -= 12;
        } else {
            ap = "am";
            if (h == 0) h = 12;
        }

        h = "0" + h;
        return h.slice(-2) + ":" + 
               m.slice(-2) + ":" + 
               s.slice(-2) + " " + ap;
    };

The code to retrieve a 12 hour time format with am/pm is more complex than the code for a 24 hour time. In either case, the digits are padded to two places. The only real process is padding left with a zero.

to24HourString: get time in 22 hour format (hh:mm:ss).

Date.prototype.to24hourString() {
        var h = "0" + this.getHours();
        var m = "0" + this.getMinutes();
        var s = "0" + this.getSeconds();
        return h.slice(-2) + ":" + m.slice(-2) + ":" + s.slice(-2);
    };

  Adding to Dates

Six methods, addDays, addWeeks, addMonths, addMonthsTrunc, addYears, and addWeekDays alter the date. Each method takes a numeric argument and changes the date by adding (or subtracting in the case of a negative argument).

addDays: add days to or subtract days from a date.

Date.prototype.addDays = function(d) {
        /* Adds the number of days to the date */
        this.setDate( this.getDate() + d );
    };

Usage:
var n = 10; var date = new Date(); date.addDays(n);

addWeeks (not demonstrated) add weeks to a date.

Date.prototype.addWeeks = function(w) {
        /* Adds the number of weeks to the date */
        this.addDays(w * 7);
    };

Usage:
var weeks = 5; var date = new Date(); date.addWeeks(weeks);

addMonths: add months to a date.

Date.prototype.addMonths = function(m) {
        /* Adds the number of months to date. */
        this.setMonth(this.getMonth() + m);
    };

Usage:
var n = 3; var date = new Date(); date.addMonths(n);

addMonthsTrunc: add months to a day adjusting month end.

Date.prototype.addMonthsTrunc = function(m) {
        // Adds the number of months to date and
        // doesn't go past last day when new month has
        // fewer days than the starting month.
        var d = this.getDate();
        this.setMonth(this.getMonth() + m);

        /* Adjust when original month has more days then new month and overflows */
        if (this.getDate() < d)
             this.setDate(0);
    };

Usage:
var n = 1; var date = new Date(2005, 1, 31); date.addMonthsTrunc(n);

addYears add years to a date.

Date.prototype.addYears = function(y) {
        // Adds the number of years to date.
        var m = this.getMonth();
        this.setFullYear(this.getFullYear() + y);

        //Adjust for leap years
        if (m < this.getMonth()) {
            this.setDate(0);
        }
    };

Usage:
var n = -3; var date = new Date(); date.addYears(n);

addWeekDays: add business or week days to a date.

Date.prototype.addWeekDays = function(d) {
    /* Adds the necessary number of days
     * to the date to include the required
     * weekdays.
     */
    var day = this.getDay();    //weekday number 0 through 6
    var wkEnd = 0;              //number of weekends needed
    var m = d % 5;              //number of weekdays for partial week

    if (d < 0) {
        wkEnd = Math.ceil(d/5);        //Yields a negative number of weekends

        switch (day) {
        case 6:
            //If staring day is Sat. one less weekend needed
            if (m == 0 && wkEnd < 0) 
                wkEnd++;
            break;
        case 0:
            if (m == 0) 
                 d++;    //decrease - part of weekend
            else 
                 d--;    //increase - part of weekend
            break;
        default:
            if (m <= -day) 
                 wkEnd--; //add weekend if not enough days to cover
        }
    }
    else if (d > 0) {
        wkEnd = Math.floor(d/5);

        switch (day) {
        case 6:
            /* If staring day is Sat. and
             * no partial week one less day needed
             * if partial week one more day needed
             */
            if (m == 0) 
                d--;
            else 
                d++;
            break;
        case 0:
            if (m == 0 && wkEnd > 0) 
                wkEnd--;
            break;
        default:
            if (5 - day < m) 
                wkEnd++;
        }
    }
    d += wkEnd * 2;
    this.addDays(d);
};

Usage:
var n = 10; var date = new Date(); date.addWeekDays(n);

Again these are easy scripts for the most part. The most interesting is addWeekDays, but before discussing that method let's quickly look at the others

addDays does exactly what you expect and there are no surprises. However, addMonths, addMonthsTrunc, and addYears are affected by months having different numbers of days when the starting date is the last day of the month. Javascript will adjust the date when the day of month number is larger than the number of days in the month by overflowing into the next month. However, generally the desired result is the last day of the month even if it is less than the starting month; i.e., the 28th for February or 30th in those months with only 30 days when the the starting day was the 31st.

addWeeks was developed in response to an email request. It simply multiplies the number of weeks by seven to get the days required and then calling addDays with those days.

The method addMonths is affected by date overflow, so adding one month to Jan 31st yields Mar 3rd (except in leap years when it gives Mar 2nd). This is adjusted in addMonthsTrunc (for truncate) and the extra days are truncated so adding a month to Jan. 31st yields Feb. 28th (unless, of course, the new date is a leap year in which case it becomes Feb. 29th).

The method addYears truncates the extra day if the starting date is Feb. 29th and the new date is not a leap year.

Many business functions depend on knowing dates that include a certain number of days the company is open for business or regular working days. addWeekDays adds the required number of weekdays to the date. Basically, it calculates the number of weekend days needed in the date range, adds that to the required weekdays and adds that number to the date. It always produces a date between Monday and Friday inclusive.

This does not take into account holidays or other special days the business is close. To account for holidays call addWeekDays in a loop that increases the required weekdays by one for every holiday in the date range from the starting date and the ending date. For example:

Example usage:

    function due_date(bizdays) {
        var today = new Date();
        var dueDate = null;
        var days = 0, holidays = 0;
        do {
            dueDate = today.copy();
            days = bizdays + holidays;
            dueDate.addWeekDays(days);
            /* Your own lookup search
             * database or array for
             * holidays between today and dueDate
             *
             * holidays = query-results
             */
        } while (days != bizdays + holidays);
        return dueDate;
    }

The function due_date assumes that a date something is due is a certain number of business days after the current date and that there is a table either a database or and array with the dates of all the holidays. Also it assumes you have some way to query this table and return the number of holidays that occur between two dates.

The loop starts by using a copy of the starting date. It adds the business days plus holidays, which is initially zero, to the starting date; thus getting an end date for the date range.

Your query is run getting the number of holidays between the start date and the date just calculated, due_date.

If the holidays plus the original business days equals the number of days used to calculate the due date your done. Otherwise, it resets the due date and tries again.

  Days, Months, or Years Between Dates

The last six methods work with two dates. One is the object whose method is being called, and the other is passed as an argument to the method. The methods, getDaysBetween, getWeekDays, getMonthsBetween, getYearsBetween, and getAge calculate the number of days, weekdays, months, or years between two dates. sameDayEachWeek returns an array of the dates for a particular day (e.g., Sunday or Monday, etc.) in each week within a date range.

Updated April 14, 2008getDaysBetween get days between two dates. Updated to account for daylight savings and standard time.

Date.prototype.getDaysBetween = function(d) {
        //Returns number of days between to dates.
        var tmp = d.copy();
        tmp.setUTCHours(this.getUTCHours(), this.getUTCMinutes(), this.getUTCSeconds(), this.getUTCMilliseconds());        

        var time = tmp.getTime() - this.getTime();
        return time/this.msPERDAY;
    };

Usage:
var endDate = new Date(2005, 11, 28); var date = new Date(); var days = date.getDaysBetween(endDate);

getWeekDays: determine number of business or weekdays between two dates

Date.prototype.getWeekDays = function(d) {
        //Returns number of weekdays between to dates
        var wkEnds = 0, days = 0;
        var s = 0, e = 0;
        days = Math.abs(this.getDaysBetween(d));

        if (days) {
            s = (d < this) ? d.getDay() : this.getDay() ;
            e = (d < this) ? this.getDay() : d.getDay();

            wkEnds = Math.floor(days/7);

            if (s != 6 && s > e) 
                wkEnds++;
            if (s != e && (s == 6 || e == 6) ) 
                days--;
            days -= (wkEnds * 2);
        }
        return days;
    };

Usage:
var endDate = new Date(2005, 12, 5); var date = new Date(); var days = date.getWeekDays(endDate);

getMonthsBetween: determine number of months between two dates.

Date.prototype.getMonthsBetween = function(d) {
        //returns months between dates
        var d1 = this.getFullYear() * 12 + this.getMonth();
        var d2 = d.getFullYear() * 12 + d.getMonth();
        return d2 - d1;
    };

Usage:
var endDate = new Date(2005, 12, 5); var date = new Date(); var months = date.getMonthsBetween(endDate);

Updated June 13, 2008 getMonthsBetween2: determine number of months between two dates adjusting for partial months. Updated to be more accurate and return two decimal places if results is not a whole number.

Date.prototype.getMonthsBetween2 = function(d) {
    var d1 = this.getFullYear() * 12 + this.getMonth();
    var d2 = d.getFullYear() * 12 + d.getMonth();
    var months = 0;
    var sDate, eDate, sign;   
    var sDay, sLastDay, sAdj, eDay, eLast, eAdj, adj;

    if (this == d) {
        months = 0;
    } else if (d1 == d2) {      //same year and month
        months = (d.getDate() - this.getDate())/this.lastday();
    } else {
        if (d1 <  d2) {
            sDate = this;
            eDate = d;
            sign = 1;
        } else {
            sDate = d;
            eDate = this;
            sign = -1;
        }

        sDay = sDate.getDate();
        sLastDay = sDate.lastday();
        eDay = eDate.getDate();
        eLastDay = eDate.lastday();

        if (sDay > eLastDay) {
            adj = eDay/eLastDay;
        } else {
            sAdj = sLastDay - sDay;
            eAdj = eDay > sLastDay ? sLastDay : eDay;
            adj = (sAdj + eAdj)/sLastDay;
        }
        months = Math.abs(d2 - d1) + (adj -1);

        if (months % 1 != 0 )
            months = (months * sign).toFixed(2);
        else
            months = (months * sign);
    }
    return months;
  };

Usage:
var months = date.getMonthsBetween2(endDate);

getYearsBetween: determine the number of years between to dates.

Date.prototype.getYearsBetween = function(d) {
        //returns years and fraction between dates
        var months = this.getMonthsBetween(d);
        return months/12;
    };

Usage:
var endDate = new Date(2005, 12, 5); var date = new Date(); var days = date.getYearsBetween(endDate);

getAge: determine age from date of birth and current date.

Date.prototype.getAge = function(d) {
        if (!d) 
            d = new Date();
        return (this.getYearsBetween(d));
    };

Usage:
var dateOfBirth = new Date(year-of-birth, month-of-birth, day-of-birth); var age = dateOfBirth.getAge();

The first two methods, getDaysBetween and getWeekDays, calculate the number of days between two dates. The first calculates the simple number of days. A negative number indicates that the date passed as an argument is earlier than the date whose method is being called. A copy of the date passed is used to avoid changing the original date. The time part of the copy is set to the time of the comparision date; thus eliminating the effect. So between Jan 1 23:59 and Jan 2 01:00 is 1 day even though it is only an hour. UTC time is used to eliminate the effect of timezones. Since the code is being run locally, the timezone adjustment only comes into play for locales that have daylight savings and standard time (summer and winter time changes).

getWeekDays uses getDaysBetween to calculate the number of days between to dates and then it calculates how many weekend days to subtract arriving at the number weekdays between the two dates. This can then be further reduced by a count of holidays in that date range.

The method getMonthsBetween calculates the number of months between two dates. And, getYearsBetween takes the result of getMonthsBetween and divides it by 12 to determine years and fraction of years.

The getAge is just a wrapper function to create a specialized case for getYearsBetween. It defaults to the current date as the end date.

sameDayEachWeek: determines number and dates of the same week day for each week between two dates.

Date.prototype.sameDayEachWeek = function (d, date) {
        /* Returns array of dates of same day each week in range */
        var aDays = new Array();
        var eDate, nextDate, adj;
        if (this > date) {
            eDate = this;
            nextDate = new Date(date.getTime());
        } else {
            eDate = date;
            nextDate = new Date(this.getTime());
        }
        /* Find when the first week day of interest occurs */
        adj = (d - nextDate.getDay() + 7) %7;
        nextDate.setDate(nextDate.getDate() + adj);
        while (nextDate < eDate) {
            aDays[aDays.length] = new Date(nextDate.getTime() );
            nextDate.setDate(nextDate.getDate() + 7);
        }
        return aDays
    };

Usage:
var endDate = new Date(2005, 12, 5); var date = new Date(); var listOfDays = date.sameDayEachWeek(2, endDate); //2 = Tuesday alert("Tuedays in the date range are:\n" + listOfDays.join("\n"));

sameDayEachWeek was developed in response to an email request. The developer needed a component that would determine the dates of a particular day of week for each week within a date range. One can imagine this used in an application that was scheduling meetings on...say Tuesday...of each week for the next two months.

The method takes a day-of-week value (0 through 6 for Sunday through Saturday) and a date object as arguments.

The first section of code calculates the earlier date: the argument or the date object calling the method. It creates a date to increment (nextDate) as a starting point and an end date. nextDate is a new date object so it can be changed without affecting the original dates.

Next we need to calculate the date the first week day of interest occurs. The tricky part is to be sure to subtract from the argument, d, before adding. Subtraction will cast a string to a number; whereas, addition will concatenate a number to a string having cast the number to a string. In some cases a string digit is likely to be passed so it needs to be cast to a number, which the subtraction will do, to get the correct results.

After that, a loop advances nextDate seven days each pass until the date is no longer in range. Each pass adds a new date object to the array. If nextDate were simply assigned to each array element, they would all be the same: the last date. This is because object assignment assigns a reference to the original so all elements would point to the same object. It is the same issue discussed in copying dates