@jsbits/add-months
Version:
Adds or subtracts N months to any JavaScript Date, local or UTC.
103 lines • 3.53 kB
JavaScript
;
/**
* Increment or decrement the given date by `count` months.
*
* @param {Date} date Local date
* @param {number} count Months to add or subtract
* @returns {Date} New local date
* @private
*/
var addMonthsLoc = function (date, count) {
// Get the day of this date, we just need to take care of days >28
var day = date.getDate();
// Set the month and change the day if it's above 28 to avoid overflow
date.setMonth(date.getMonth() + count, day > 28 ? 28 : day);
// Restore the day if necessary, preserving the month and we are done.
if (day > 28) {
var month = date.getMonth();
/*
"If there is an overflow in the day, the date is adjusted to the last
valid day of the expected month."
*/
date.setDate(day);
if (date.getMonth() !== month) {
date.setDate(0);
}
}
return date;
};
/**
* Like the `addMonthsLoc` function, but using UTC methods.
*
* @param {Date} date UTC date
* @param {number} count Months to add or subtract
* @returns {Date} New UTC date
* @private
*/
var addMonthsUTC = function (date, count) {
var day = date.getUTCDate();
date.setUTCMonth(date.getUTCMonth() + count, day > 28 ? 28 : day);
if (day > 28) {
var month = date.getUTCMonth();
date.setUTCDate(day);
if (date.getUTCMonth() !== month) {
date.setUTCDate(0);
}
}
return date;
};
/** Shortcut */
var _toString = Object.prototype.toString;
/**
* Convert a number or Date object to a Date, for other types, returns
* an invalid date (i.e. NaN).
*
* @param {*} src Date or number
* @return {Date} Parsed date
* @private
*/
var toDate = function (src) {
var type = _toString.call(src);
return new Date(type === '[object Date]' || type === '[object Number]' ? +src : NaN);
};
/**
* Returns a date occurring `count` months after `startdate` or, if `count` is
* negative, the date occurring `count` months before `startdate`.
*
* - If `startdate` is not a Date or number that can be converted to a
* valid date, returns a new Date instance with an invalid date.
*
* - If `count` is evaluated as zero, returns a new Date instance with the
* the same value as `startdate`.
*
* - If there is an overflow in the day, the date is adjusted to the last
* valid day of the expected month.
*
* The third parameter is optional and indicates if the date is UTC. It is
* necessary to differentiate UTC dates from locals and avoid errors due to the
* [Daylight Saving Time](https://en.wikipedia.org/wiki/Daylight_saving_time)
* (DST).
*
* This function does not change the original date.
*
* @param {Date|number} startdate A value parseable as a JavaScript Date
* @param {number} count Number of months to add or subtract
* @param {boolean} [asUTC=false] If `true`, handle the date as UTC
* @returns {Date} A new, adjusted Date instance.
* @since 1.0.0
*/
var addMonths = function _addMonths(startdate, count, asUTC) {
// Create a new `Date` instance.
// Wrong types return NaN dates without throwing exceptions.
var date = toDate(startdate);
// Corce `count` with 'ToInt32'
count |= 0;
// Filter out zero count and invalid dates.
if (!count || isNaN(date)) {
return date;
}
// Return the result with the UTC methods if required by the flags
return asUTC ? addMonthsUTC(date, count) : addMonthsLoc(date, count);
};
module.exports = addMonths;
//# sourceMappingURL=index.js.map