UNPKG

materialui-daterange-picker

Version:

A react date range picker implementation using @material-ui.

1,638 lines (1,455 loc) 194 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } var React = require('react'); var React__default = _interopDefault(React); var styles = require('@material-ui/core/styles'); var core = require('@material-ui/core'); var SvgIcon = _interopDefault(require('@material-ui/core/SvgIcon')); /*! ***************************************************************************** Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. See the Apache Version 2.0 License for specific language governing permissions and limitations under the License. ***************************************************************************** */ var __assign = function() { __assign = Object.assign || function __assign(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; function unwrapExports (x) { return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; } function createCommonjsModule(fn, module) { return module = { exports: {} }, fn(module, module.exports), module.exports; } var classnames = createCommonjsModule(function (module) { /*! Copyright (c) 2017 Jed Watson. Licensed under the MIT License (MIT), see http://jedwatson.github.io/classnames */ /* global define */ (function () { var hasOwn = {}.hasOwnProperty; function classNames () { var classes = []; for (var i = 0; i < arguments.length; i++) { var arg = arguments[i]; if (!arg) continue; var argType = typeof arg; if (argType === 'string' || argType === 'number') { classes.push(arg); } else if (Array.isArray(arg) && arg.length) { var inner = classNames.apply(null, arg); if (inner) { classes.push(inner); } } else if (argType === 'object') { for (var key in arg) { if (hasOwn.call(arg, key) && arg[key]) { classes.push(key); } } } } return classes.join(' '); } if ( module.exports) { classNames.default = classNames; module.exports = classNames; } else { window.classNames = classNames; } }()); }); var MILLISECONDS_IN_MINUTE = 60000; /** * Google Chrome as of 67.0.3396.87 introduced timezones with offset that includes seconds. * They usually appear for dates that denote time before the timezones were introduced * (e.g. for 'Europe/Prague' timezone the offset is GMT+00:57:44 before 1 October 1891 * and GMT+01:00:00 after that date) * * Date#getTimezoneOffset returns the offset in minutes and would return 57 for the example above, * which would lead to incorrect calculations. * * This function returns the timezone offset in milliseconds that takes seconds in account. */ var getTimezoneOffsetInMilliseconds = function getTimezoneOffsetInMilliseconds (dirtyDate) { var date = new Date(dirtyDate.getTime()); var baseTimezoneOffset = date.getTimezoneOffset(); date.setSeconds(0, 0); var millisecondsPartOfTimezoneOffset = date.getTime() % MILLISECONDS_IN_MINUTE; return baseTimezoneOffset * MILLISECONDS_IN_MINUTE + millisecondsPartOfTimezoneOffset }; /** * @category Common Helpers * @summary Is the given argument an instance of Date? * * @description * Is the given argument an instance of Date? * * @param {*} argument - the argument to check * @returns {Boolean} the given argument is an instance of Date * * @example * // Is 'mayonnaise' a Date? * var result = isDate('mayonnaise') * //=> false */ function isDate (argument) { return argument instanceof Date } var is_date = isDate; var MILLISECONDS_IN_HOUR = 3600000; var MILLISECONDS_IN_MINUTE$1 = 60000; var DEFAULT_ADDITIONAL_DIGITS = 2; var parseTokenDateTimeDelimeter = /[T ]/; var parseTokenPlainTime = /:/; // year tokens var parseTokenYY = /^(\d{2})$/; var parseTokensYYY = [ /^([+-]\d{2})$/, // 0 additional digits /^([+-]\d{3})$/, // 1 additional digit /^([+-]\d{4})$/ // 2 additional digits ]; var parseTokenYYYY = /^(\d{4})/; var parseTokensYYYYY = [ /^([+-]\d{4})/, // 0 additional digits /^([+-]\d{5})/, // 1 additional digit /^([+-]\d{6})/ // 2 additional digits ]; // date tokens var parseTokenMM = /^-(\d{2})$/; var parseTokenDDD = /^-?(\d{3})$/; var parseTokenMMDD = /^-?(\d{2})-?(\d{2})$/; var parseTokenWww = /^-?W(\d{2})$/; var parseTokenWwwD = /^-?W(\d{2})-?(\d{1})$/; // time tokens var parseTokenHH = /^(\d{2}([.,]\d*)?)$/; var parseTokenHHMM = /^(\d{2}):?(\d{2}([.,]\d*)?)$/; var parseTokenHHMMSS = /^(\d{2}):?(\d{2}):?(\d{2}([.,]\d*)?)$/; // timezone tokens var parseTokenTimezone = /([Z+-].*)$/; var parseTokenTimezoneZ = /^(Z)$/; var parseTokenTimezoneHH = /^([+-])(\d{2})$/; var parseTokenTimezoneHHMM = /^([+-])(\d{2}):?(\d{2})$/; /** * @category Common Helpers * @summary Convert the given argument to an instance of Date. * * @description * Convert the given argument to an instance of Date. * * If the argument is an instance of Date, the function returns its clone. * * If the argument is a number, it is treated as a timestamp. * * If an argument is a string, the function tries to parse it. * Function accepts complete ISO 8601 formats as well as partial implementations. * ISO 8601: http://en.wikipedia.org/wiki/ISO_8601 * * If all above fails, the function passes the given argument to Date constructor. * * @param {Date|String|Number} argument - the value to convert * @param {Object} [options] - the object with options * @param {0 | 1 | 2} [options.additionalDigits=2] - the additional number of digits in the extended year format * @returns {Date} the parsed date in the local time zone * * @example * // Convert string '2014-02-11T11:30:30' to date: * var result = parse('2014-02-11T11:30:30') * //=> Tue Feb 11 2014 11:30:30 * * @example * // Parse string '+02014101', * // if the additional number of digits in the extended year format is 1: * var result = parse('+02014101', {additionalDigits: 1}) * //=> Fri Apr 11 2014 00:00:00 */ function parse (argument, dirtyOptions) { if (is_date(argument)) { // Prevent the date to lose the milliseconds when passed to new Date() in IE10 return new Date(argument.getTime()) } else if (typeof argument !== 'string') { return new Date(argument) } var options = dirtyOptions || {}; var additionalDigits = options.additionalDigits; if (additionalDigits == null) { additionalDigits = DEFAULT_ADDITIONAL_DIGITS; } else { additionalDigits = Number(additionalDigits); } var dateStrings = splitDateString(argument); var parseYearResult = parseYear(dateStrings.date, additionalDigits); var year = parseYearResult.year; var restDateString = parseYearResult.restDateString; var date = parseDate(restDateString, year); if (date) { var timestamp = date.getTime(); var time = 0; var offset; if (dateStrings.time) { time = parseTime(dateStrings.time); } if (dateStrings.timezone) { offset = parseTimezone(dateStrings.timezone) * MILLISECONDS_IN_MINUTE$1; } else { var fullTime = timestamp + time; var fullTimeDate = new Date(fullTime); offset = getTimezoneOffsetInMilliseconds(fullTimeDate); // Adjust time when it's coming from DST var fullTimeDateNextDay = new Date(fullTime); fullTimeDateNextDay.setDate(fullTimeDate.getDate() + 1); var offsetDiff = getTimezoneOffsetInMilliseconds(fullTimeDateNextDay) - getTimezoneOffsetInMilliseconds(fullTimeDate); if (offsetDiff > 0) { offset += offsetDiff; } } return new Date(timestamp + time + offset) } else { return new Date(argument) } } function splitDateString (dateString) { var dateStrings = {}; var array = dateString.split(parseTokenDateTimeDelimeter); var timeString; if (parseTokenPlainTime.test(array[0])) { dateStrings.date = null; timeString = array[0]; } else { dateStrings.date = array[0]; timeString = array[1]; } if (timeString) { var token = parseTokenTimezone.exec(timeString); if (token) { dateStrings.time = timeString.replace(token[1], ''); dateStrings.timezone = token[1]; } else { dateStrings.time = timeString; } } return dateStrings } function parseYear (dateString, additionalDigits) { var parseTokenYYY = parseTokensYYY[additionalDigits]; var parseTokenYYYYY = parseTokensYYYYY[additionalDigits]; var token; // YYYY or ±YYYYY token = parseTokenYYYY.exec(dateString) || parseTokenYYYYY.exec(dateString); if (token) { var yearString = token[1]; return { year: parseInt(yearString, 10), restDateString: dateString.slice(yearString.length) } } // YY or ±YYY token = parseTokenYY.exec(dateString) || parseTokenYYY.exec(dateString); if (token) { var centuryString = token[1]; return { year: parseInt(centuryString, 10) * 100, restDateString: dateString.slice(centuryString.length) } } // Invalid ISO-formatted year return { year: null } } function parseDate (dateString, year) { // Invalid ISO-formatted year if (year === null) { return null } var token; var date; var month; var week; // YYYY if (dateString.length === 0) { date = new Date(0); date.setUTCFullYear(year); return date } // YYYY-MM token = parseTokenMM.exec(dateString); if (token) { date = new Date(0); month = parseInt(token[1], 10) - 1; date.setUTCFullYear(year, month); return date } // YYYY-DDD or YYYYDDD token = parseTokenDDD.exec(dateString); if (token) { date = new Date(0); var dayOfYear = parseInt(token[1], 10); date.setUTCFullYear(year, 0, dayOfYear); return date } // YYYY-MM-DD or YYYYMMDD token = parseTokenMMDD.exec(dateString); if (token) { date = new Date(0); month = parseInt(token[1], 10) - 1; var day = parseInt(token[2], 10); date.setUTCFullYear(year, month, day); return date } // YYYY-Www or YYYYWww token = parseTokenWww.exec(dateString); if (token) { week = parseInt(token[1], 10) - 1; return dayOfISOYear(year, week) } // YYYY-Www-D or YYYYWwwD token = parseTokenWwwD.exec(dateString); if (token) { week = parseInt(token[1], 10) - 1; var dayOfWeek = parseInt(token[2], 10) - 1; return dayOfISOYear(year, week, dayOfWeek) } // Invalid ISO-formatted date return null } function parseTime (timeString) { var token; var hours; var minutes; // hh token = parseTokenHH.exec(timeString); if (token) { hours = parseFloat(token[1].replace(',', '.')); return (hours % 24) * MILLISECONDS_IN_HOUR } // hh:mm or hhmm token = parseTokenHHMM.exec(timeString); if (token) { hours = parseInt(token[1], 10); minutes = parseFloat(token[2].replace(',', '.')); return (hours % 24) * MILLISECONDS_IN_HOUR + minutes * MILLISECONDS_IN_MINUTE$1 } // hh:mm:ss or hhmmss token = parseTokenHHMMSS.exec(timeString); if (token) { hours = parseInt(token[1], 10); minutes = parseInt(token[2], 10); var seconds = parseFloat(token[3].replace(',', '.')); return (hours % 24) * MILLISECONDS_IN_HOUR + minutes * MILLISECONDS_IN_MINUTE$1 + seconds * 1000 } // Invalid ISO-formatted time return null } function parseTimezone (timezoneString) { var token; var absoluteOffset; // Z token = parseTokenTimezoneZ.exec(timezoneString); if (token) { return 0 } // ±hh token = parseTokenTimezoneHH.exec(timezoneString); if (token) { absoluteOffset = parseInt(token[2], 10) * 60; return (token[1] === '+') ? -absoluteOffset : absoluteOffset } // ±hh:mm or ±hhmm token = parseTokenTimezoneHHMM.exec(timezoneString); if (token) { absoluteOffset = parseInt(token[2], 10) * 60 + parseInt(token[3], 10); return (token[1] === '+') ? -absoluteOffset : absoluteOffset } return 0 } function dayOfISOYear (isoYear, week, day) { week = week || 0; day = day || 0; var date = new Date(0); date.setUTCFullYear(isoYear, 0, 4); var fourthOfJanuaryDay = date.getUTCDay() || 7; var diff = week * 7 + day + 1 - fourthOfJanuaryDay; date.setUTCDate(date.getUTCDate() + diff); return date } var parse_1 = parse; /** * @category Day Helpers * @summary Add the specified number of days to the given date. * * @description * Add the specified number of days to the given date. * * @param {Date|String|Number} date - the date to be changed * @param {Number} amount - the amount of days to be added * @returns {Date} the new date with the days added * * @example * // Add 10 days to 1 September 2014: * var result = addDays(new Date(2014, 8, 1), 10) * //=> Thu Sep 11 2014 00:00:00 */ function addDays (dirtyDate, dirtyAmount) { var date = parse_1(dirtyDate); var amount = Number(dirtyAmount); date.setDate(date.getDate() + amount); return date } var add_days = addDays; /** * @category Millisecond Helpers * @summary Add the specified number of milliseconds to the given date. * * @description * Add the specified number of milliseconds to the given date. * * @param {Date|String|Number} date - the date to be changed * @param {Number} amount - the amount of milliseconds to be added * @returns {Date} the new date with the milliseconds added * * @example * // Add 750 milliseconds to 10 July 2014 12:45:30.000: * var result = addMilliseconds(new Date(2014, 6, 10, 12, 45, 30, 0), 750) * //=> Thu Jul 10 2014 12:45:30.750 */ function addMilliseconds (dirtyDate, dirtyAmount) { var timestamp = parse_1(dirtyDate).getTime(); var amount = Number(dirtyAmount); return new Date(timestamp + amount) } var add_milliseconds = addMilliseconds; var MILLISECONDS_IN_HOUR$1 = 3600000; /** * @category Hour Helpers * @summary Add the specified number of hours to the given date. * * @description * Add the specified number of hours to the given date. * * @param {Date|String|Number} date - the date to be changed * @param {Number} amount - the amount of hours to be added * @returns {Date} the new date with the hours added * * @example * // Add 2 hours to 10 July 2014 23:00:00: * var result = addHours(new Date(2014, 6, 10, 23, 0), 2) * //=> Fri Jul 11 2014 01:00:00 */ function addHours (dirtyDate, dirtyAmount) { var amount = Number(dirtyAmount); return add_milliseconds(dirtyDate, amount * MILLISECONDS_IN_HOUR$1) } var add_hours = addHours; /** * @category Week Helpers * @summary Return the start of a week for the given date. * * @description * Return the start of a week for the given date. * The result will be in the local timezone. * * @param {Date|String|Number} date - the original date * @param {Object} [options] - the object with options * @param {Number} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday) * @returns {Date} the start of a week * * @example * // The start of a week for 2 September 2014 11:55:00: * var result = startOfWeek(new Date(2014, 8, 2, 11, 55, 0)) * //=> Sun Aug 31 2014 00:00:00 * * @example * // If the week starts on Monday, the start of the week for 2 September 2014 11:55:00: * var result = startOfWeek(new Date(2014, 8, 2, 11, 55, 0), {weekStartsOn: 1}) * //=> Mon Sep 01 2014 00:00:00 */ function startOfWeek (dirtyDate, dirtyOptions) { var weekStartsOn = dirtyOptions ? (Number(dirtyOptions.weekStartsOn) || 0) : 0; var date = parse_1(dirtyDate); var day = date.getDay(); var diff = (day < weekStartsOn ? 7 : 0) + day - weekStartsOn; date.setDate(date.getDate() - diff); date.setHours(0, 0, 0, 0); return date } var start_of_week = startOfWeek; /** * @category ISO Week Helpers * @summary Return the start of an ISO week for the given date. * * @description * Return the start of an ISO week for the given date. * The result will be in the local timezone. * * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date * * @param {Date|String|Number} date - the original date * @returns {Date} the start of an ISO week * * @example * // The start of an ISO week for 2 September 2014 11:55:00: * var result = startOfISOWeek(new Date(2014, 8, 2, 11, 55, 0)) * //=> Mon Sep 01 2014 00:00:00 */ function startOfISOWeek (dirtyDate) { return start_of_week(dirtyDate, {weekStartsOn: 1}) } var start_of_iso_week = startOfISOWeek; /** * @category ISO Week-Numbering Year Helpers * @summary Get the ISO week-numbering year of the given date. * * @description * Get the ISO week-numbering year of the given date, * which always starts 3 days before the year's first Thursday. * * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date * * @param {Date|String|Number} date - the given date * @returns {Number} the ISO week-numbering year * * @example * // Which ISO-week numbering year is 2 January 2005? * var result = getISOYear(new Date(2005, 0, 2)) * //=> 2004 */ function getISOYear (dirtyDate) { var date = parse_1(dirtyDate); var year = date.getFullYear(); var fourthOfJanuaryOfNextYear = new Date(0); fourthOfJanuaryOfNextYear.setFullYear(year + 1, 0, 4); fourthOfJanuaryOfNextYear.setHours(0, 0, 0, 0); var startOfNextYear = start_of_iso_week(fourthOfJanuaryOfNextYear); var fourthOfJanuaryOfThisYear = new Date(0); fourthOfJanuaryOfThisYear.setFullYear(year, 0, 4); fourthOfJanuaryOfThisYear.setHours(0, 0, 0, 0); var startOfThisYear = start_of_iso_week(fourthOfJanuaryOfThisYear); if (date.getTime() >= startOfNextYear.getTime()) { return year + 1 } else if (date.getTime() >= startOfThisYear.getTime()) { return year } else { return year - 1 } } var get_iso_year = getISOYear; /** * @category ISO Week-Numbering Year Helpers * @summary Return the start of an ISO week-numbering year for the given date. * * @description * Return the start of an ISO week-numbering year, * which always starts 3 days before the year's first Thursday. * The result will be in the local timezone. * * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date * * @param {Date|String|Number} date - the original date * @returns {Date} the start of an ISO year * * @example * // The start of an ISO week-numbering year for 2 July 2005: * var result = startOfISOYear(new Date(2005, 6, 2)) * //=> Mon Jan 03 2005 00:00:00 */ function startOfISOYear (dirtyDate) { var year = get_iso_year(dirtyDate); var fourthOfJanuary = new Date(0); fourthOfJanuary.setFullYear(year, 0, 4); fourthOfJanuary.setHours(0, 0, 0, 0); var date = start_of_iso_week(fourthOfJanuary); return date } var start_of_iso_year = startOfISOYear; /** * @category Day Helpers * @summary Return the start of a day for the given date. * * @description * Return the start of a day for the given date. * The result will be in the local timezone. * * @param {Date|String|Number} date - the original date * @returns {Date} the start of a day * * @example * // The start of a day for 2 September 2014 11:55:00: * var result = startOfDay(new Date(2014, 8, 2, 11, 55, 0)) * //=> Tue Sep 02 2014 00:00:00 */ function startOfDay (dirtyDate) { var date = parse_1(dirtyDate); date.setHours(0, 0, 0, 0); return date } var start_of_day = startOfDay; var MILLISECONDS_IN_MINUTE$2 = 60000; var MILLISECONDS_IN_DAY = 86400000; /** * @category Day Helpers * @summary Get the number of calendar days between the given dates. * * @description * Get the number of calendar days between the given dates. * * @param {Date|String|Number} dateLeft - the later date * @param {Date|String|Number} dateRight - the earlier date * @returns {Number} the number of calendar days * * @example * // How many calendar days are between * // 2 July 2011 23:00:00 and 2 July 2012 00:00:00? * var result = differenceInCalendarDays( * new Date(2012, 6, 2, 0, 0), * new Date(2011, 6, 2, 23, 0) * ) * //=> 366 */ function differenceInCalendarDays (dirtyDateLeft, dirtyDateRight) { var startOfDayLeft = start_of_day(dirtyDateLeft); var startOfDayRight = start_of_day(dirtyDateRight); var timestampLeft = startOfDayLeft.getTime() - startOfDayLeft.getTimezoneOffset() * MILLISECONDS_IN_MINUTE$2; var timestampRight = startOfDayRight.getTime() - startOfDayRight.getTimezoneOffset() * MILLISECONDS_IN_MINUTE$2; // Round the number of days to the nearest integer // because the number of milliseconds in a day is not constant // (e.g. it's different in the day of the daylight saving time clock shift) return Math.round((timestampLeft - timestampRight) / MILLISECONDS_IN_DAY) } var difference_in_calendar_days = differenceInCalendarDays; /** * @category ISO Week-Numbering Year Helpers * @summary Set the ISO week-numbering year to the given date. * * @description * Set the ISO week-numbering year to the given date, * saving the week number and the weekday number. * * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date * * @param {Date|String|Number} date - the date to be changed * @param {Number} isoYear - the ISO week-numbering year of the new date * @returns {Date} the new date with the ISO week-numbering year setted * * @example * // Set ISO week-numbering year 2007 to 29 December 2008: * var result = setISOYear(new Date(2008, 11, 29), 2007) * //=> Mon Jan 01 2007 00:00:00 */ function setISOYear (dirtyDate, dirtyISOYear) { var date = parse_1(dirtyDate); var isoYear = Number(dirtyISOYear); var diff = difference_in_calendar_days(date, start_of_iso_year(date)); var fourthOfJanuary = new Date(0); fourthOfJanuary.setFullYear(isoYear, 0, 4); fourthOfJanuary.setHours(0, 0, 0, 0); date = start_of_iso_year(fourthOfJanuary); date.setDate(date.getDate() + diff); return date } var set_iso_year = setISOYear; /** * @category ISO Week-Numbering Year Helpers * @summary Add the specified number of ISO week-numbering years to the given date. * * @description * Add the specified number of ISO week-numbering years to the given date. * * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date * * @param {Date|String|Number} date - the date to be changed * @param {Number} amount - the amount of ISO week-numbering years to be added * @returns {Date} the new date with the ISO week-numbering years added * * @example * // Add 5 ISO week-numbering years to 2 July 2010: * var result = addISOYears(new Date(2010, 6, 2), 5) * //=> Fri Jun 26 2015 00:00:00 */ function addISOYears (dirtyDate, dirtyAmount) { var amount = Number(dirtyAmount); return set_iso_year(dirtyDate, get_iso_year(dirtyDate) + amount) } var add_iso_years = addISOYears; var MILLISECONDS_IN_MINUTE$3 = 60000; /** * @category Minute Helpers * @summary Add the specified number of minutes to the given date. * * @description * Add the specified number of minutes to the given date. * * @param {Date|String|Number} date - the date to be changed * @param {Number} amount - the amount of minutes to be added * @returns {Date} the new date with the minutes added * * @example * // Add 30 minutes to 10 July 2014 12:00:00: * var result = addMinutes(new Date(2014, 6, 10, 12, 0), 30) * //=> Thu Jul 10 2014 12:30:00 */ function addMinutes (dirtyDate, dirtyAmount) { var amount = Number(dirtyAmount); return add_milliseconds(dirtyDate, amount * MILLISECONDS_IN_MINUTE$3) } var add_minutes = addMinutes; /** * @category Month Helpers * @summary Get the number of days in a month of the given date. * * @description * Get the number of days in a month of the given date. * * @param {Date|String|Number} date - the given date * @returns {Number} the number of days in a month * * @example * // How many days are in February 2000? * var result = getDaysInMonth(new Date(2000, 1)) * //=> 29 */ function getDaysInMonth (dirtyDate) { var date = parse_1(dirtyDate); var year = date.getFullYear(); var monthIndex = date.getMonth(); var lastDayOfMonth = new Date(0); lastDayOfMonth.setFullYear(year, monthIndex + 1, 0); lastDayOfMonth.setHours(0, 0, 0, 0); return lastDayOfMonth.getDate() } var get_days_in_month = getDaysInMonth; /** * @category Month Helpers * @summary Add the specified number of months to the given date. * * @description * Add the specified number of months to the given date. * * @param {Date|String|Number} date - the date to be changed * @param {Number} amount - the amount of months to be added * @returns {Date} the new date with the months added * * @example * // Add 5 months to 1 September 2014: * var result = addMonths(new Date(2014, 8, 1), 5) * //=> Sun Feb 01 2015 00:00:00 */ function addMonths (dirtyDate, dirtyAmount) { var date = parse_1(dirtyDate); var amount = Number(dirtyAmount); var desiredMonth = date.getMonth() + amount; var dateWithDesiredMonth = new Date(0); dateWithDesiredMonth.setFullYear(date.getFullYear(), desiredMonth, 1); dateWithDesiredMonth.setHours(0, 0, 0, 0); var daysInMonth = get_days_in_month(dateWithDesiredMonth); // Set the last day of the new month // if the original date was the last day of the longer month date.setMonth(desiredMonth, Math.min(daysInMonth, date.getDate())); return date } var add_months = addMonths; /** * @category Quarter Helpers * @summary Add the specified number of year quarters to the given date. * * @description * Add the specified number of year quarters to the given date. * * @param {Date|String|Number} date - the date to be changed * @param {Number} amount - the amount of quarters to be added * @returns {Date} the new date with the quarters added * * @example * // Add 1 quarter to 1 September 2014: * var result = addQuarters(new Date(2014, 8, 1), 1) * //=> Mon Dec 01 2014 00:00:00 */ function addQuarters (dirtyDate, dirtyAmount) { var amount = Number(dirtyAmount); var months = amount * 3; return add_months(dirtyDate, months) } var add_quarters = addQuarters; /** * @category Second Helpers * @summary Add the specified number of seconds to the given date. * * @description * Add the specified number of seconds to the given date. * * @param {Date|String|Number} date - the date to be changed * @param {Number} amount - the amount of seconds to be added * @returns {Date} the new date with the seconds added * * @example * // Add 30 seconds to 10 July 2014 12:45:00: * var result = addSeconds(new Date(2014, 6, 10, 12, 45, 0), 30) * //=> Thu Jul 10 2014 12:45:30 */ function addSeconds (dirtyDate, dirtyAmount) { var amount = Number(dirtyAmount); return add_milliseconds(dirtyDate, amount * 1000) } var add_seconds = addSeconds; /** * @category Week Helpers * @summary Add the specified number of weeks to the given date. * * @description * Add the specified number of week to the given date. * * @param {Date|String|Number} date - the date to be changed * @param {Number} amount - the amount of weeks to be added * @returns {Date} the new date with the weeks added * * @example * // Add 4 weeks to 1 September 2014: * var result = addWeeks(new Date(2014, 8, 1), 4) * //=> Mon Sep 29 2014 00:00:00 */ function addWeeks (dirtyDate, dirtyAmount) { var amount = Number(dirtyAmount); var days = amount * 7; return add_days(dirtyDate, days) } var add_weeks = addWeeks; /** * @category Year Helpers * @summary Add the specified number of years to the given date. * * @description * Add the specified number of years to the given date. * * @param {Date|String|Number} date - the date to be changed * @param {Number} amount - the amount of years to be added * @returns {Date} the new date with the years added * * @example * // Add 5 years to 1 September 2014: * var result = addYears(new Date(2014, 8, 1), 5) * //=> Sun Sep 01 2019 00:00:00 */ function addYears (dirtyDate, dirtyAmount) { var amount = Number(dirtyAmount); return add_months(dirtyDate, amount * 12) } var add_years = addYears; /** * @category Range Helpers * @summary Is the given date range overlapping with another date range? * * @description * Is the given date range overlapping with another date range? * * @param {Date|String|Number} initialRangeStartDate - the start of the initial range * @param {Date|String|Number} initialRangeEndDate - the end of the initial range * @param {Date|String|Number} comparedRangeStartDate - the start of the range to compare it with * @param {Date|String|Number} comparedRangeEndDate - the end of the range to compare it with * @returns {Boolean} whether the date ranges are overlapping * @throws {Error} startDate of a date range cannot be after its endDate * * @example * // For overlapping date ranges: * areRangesOverlapping( * new Date(2014, 0, 10), new Date(2014, 0, 20), new Date(2014, 0, 17), new Date(2014, 0, 21) * ) * //=> true * * @example * // For non-overlapping date ranges: * areRangesOverlapping( * new Date(2014, 0, 10), new Date(2014, 0, 20), new Date(2014, 0, 21), new Date(2014, 0, 22) * ) * //=> false */ function areRangesOverlapping (dirtyInitialRangeStartDate, dirtyInitialRangeEndDate, dirtyComparedRangeStartDate, dirtyComparedRangeEndDate) { var initialStartTime = parse_1(dirtyInitialRangeStartDate).getTime(); var initialEndTime = parse_1(dirtyInitialRangeEndDate).getTime(); var comparedStartTime = parse_1(dirtyComparedRangeStartDate).getTime(); var comparedEndTime = parse_1(dirtyComparedRangeEndDate).getTime(); if (initialStartTime > initialEndTime || comparedStartTime > comparedEndTime) { throw new Error('The start of the range cannot be after the end of the range') } return initialStartTime < comparedEndTime && comparedStartTime < initialEndTime } var are_ranges_overlapping = areRangesOverlapping; /** * @category Common Helpers * @summary Return an index of the closest date from the array comparing to the given date. * * @description * Return an index of the closest date from the array comparing to the given date. * * @param {Date|String|Number} dateToCompare - the date to compare with * @param {Date[]|String[]|Number[]} datesArray - the array to search * @returns {Number} an index of the date closest to the given date * @throws {TypeError} the second argument must be an instance of Array * * @example * // Which date is closer to 6 September 2015? * var dateToCompare = new Date(2015, 8, 6) * var datesArray = [ * new Date(2015, 0, 1), * new Date(2016, 0, 1), * new Date(2017, 0, 1) * ] * var result = closestIndexTo(dateToCompare, datesArray) * //=> 1 */ function closestIndexTo (dirtyDateToCompare, dirtyDatesArray) { if (!(dirtyDatesArray instanceof Array)) { throw new TypeError(toString.call(dirtyDatesArray) + ' is not an instance of Array') } var dateToCompare = parse_1(dirtyDateToCompare); var timeToCompare = dateToCompare.getTime(); var result; var minDistance; dirtyDatesArray.forEach(function (dirtyDate, index) { var currentDate = parse_1(dirtyDate); var distance = Math.abs(timeToCompare - currentDate.getTime()); if (result === undefined || distance < minDistance) { result = index; minDistance = distance; } }); return result } var closest_index_to = closestIndexTo; /** * @category Common Helpers * @summary Return a date from the array closest to the given date. * * @description * Return a date from the array closest to the given date. * * @param {Date|String|Number} dateToCompare - the date to compare with * @param {Date[]|String[]|Number[]} datesArray - the array to search * @returns {Date} the date from the array closest to the given date * @throws {TypeError} the second argument must be an instance of Array * * @example * // Which date is closer to 6 September 2015: 1 January 2000 or 1 January 2030? * var dateToCompare = new Date(2015, 8, 6) * var result = closestTo(dateToCompare, [ * new Date(2000, 0, 1), * new Date(2030, 0, 1) * ]) * //=> Tue Jan 01 2030 00:00:00 */ function closestTo (dirtyDateToCompare, dirtyDatesArray) { if (!(dirtyDatesArray instanceof Array)) { throw new TypeError(toString.call(dirtyDatesArray) + ' is not an instance of Array') } var dateToCompare = parse_1(dirtyDateToCompare); var timeToCompare = dateToCompare.getTime(); var result; var minDistance; dirtyDatesArray.forEach(function (dirtyDate) { var currentDate = parse_1(dirtyDate); var distance = Math.abs(timeToCompare - currentDate.getTime()); if (result === undefined || distance < minDistance) { result = currentDate; minDistance = distance; } }); return result } var closest_to = closestTo; /** * @category Common Helpers * @summary Compare the two dates and return -1, 0 or 1. * * @description * Compare the two dates and return 1 if the first date is after the second, * -1 if the first date is before the second or 0 if dates are equal. * * @param {Date|String|Number} dateLeft - the first date to compare * @param {Date|String|Number} dateRight - the second date to compare * @returns {Number} the result of the comparison * * @example * // Compare 11 February 1987 and 10 July 1989: * var result = compareAsc( * new Date(1987, 1, 11), * new Date(1989, 6, 10) * ) * //=> -1 * * @example * // Sort the array of dates: * var result = [ * new Date(1995, 6, 2), * new Date(1987, 1, 11), * new Date(1989, 6, 10) * ].sort(compareAsc) * //=> [ * // Wed Feb 11 1987 00:00:00, * // Mon Jul 10 1989 00:00:00, * // Sun Jul 02 1995 00:00:00 * // ] */ function compareAsc (dirtyDateLeft, dirtyDateRight) { var dateLeft = parse_1(dirtyDateLeft); var timeLeft = dateLeft.getTime(); var dateRight = parse_1(dirtyDateRight); var timeRight = dateRight.getTime(); if (timeLeft < timeRight) { return -1 } else if (timeLeft > timeRight) { return 1 } else { return 0 } } var compare_asc = compareAsc; /** * @category Common Helpers * @summary Compare the two dates reverse chronologically and return -1, 0 or 1. * * @description * Compare the two dates and return -1 if the first date is after the second, * 1 if the first date is before the second or 0 if dates are equal. * * @param {Date|String|Number} dateLeft - the first date to compare * @param {Date|String|Number} dateRight - the second date to compare * @returns {Number} the result of the comparison * * @example * // Compare 11 February 1987 and 10 July 1989 reverse chronologically: * var result = compareDesc( * new Date(1987, 1, 11), * new Date(1989, 6, 10) * ) * //=> 1 * * @example * // Sort the array of dates in reverse chronological order: * var result = [ * new Date(1995, 6, 2), * new Date(1987, 1, 11), * new Date(1989, 6, 10) * ].sort(compareDesc) * //=> [ * // Sun Jul 02 1995 00:00:00, * // Mon Jul 10 1989 00:00:00, * // Wed Feb 11 1987 00:00:00 * // ] */ function compareDesc (dirtyDateLeft, dirtyDateRight) { var dateLeft = parse_1(dirtyDateLeft); var timeLeft = dateLeft.getTime(); var dateRight = parse_1(dirtyDateRight); var timeRight = dateRight.getTime(); if (timeLeft > timeRight) { return -1 } else if (timeLeft < timeRight) { return 1 } else { return 0 } } var compare_desc = compareDesc; var MILLISECONDS_IN_MINUTE$4 = 60000; var MILLISECONDS_IN_WEEK = 604800000; /** * @category ISO Week Helpers * @summary Get the number of calendar ISO weeks between the given dates. * * @description * Get the number of calendar ISO weeks between the given dates. * * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date * * @param {Date|String|Number} dateLeft - the later date * @param {Date|String|Number} dateRight - the earlier date * @returns {Number} the number of calendar ISO weeks * * @example * // How many calendar ISO weeks are between 6 July 2014 and 21 July 2014? * var result = differenceInCalendarISOWeeks( * new Date(2014, 6, 21), * new Date(2014, 6, 6) * ) * //=> 3 */ function differenceInCalendarISOWeeks (dirtyDateLeft, dirtyDateRight) { var startOfISOWeekLeft = start_of_iso_week(dirtyDateLeft); var startOfISOWeekRight = start_of_iso_week(dirtyDateRight); var timestampLeft = startOfISOWeekLeft.getTime() - startOfISOWeekLeft.getTimezoneOffset() * MILLISECONDS_IN_MINUTE$4; var timestampRight = startOfISOWeekRight.getTime() - startOfISOWeekRight.getTimezoneOffset() * MILLISECONDS_IN_MINUTE$4; // Round the number of days to the nearest integer // because the number of milliseconds in a week is not constant // (e.g. it's different in the week of the daylight saving time clock shift) return Math.round((timestampLeft - timestampRight) / MILLISECONDS_IN_WEEK) } var difference_in_calendar_iso_weeks = differenceInCalendarISOWeeks; /** * @category ISO Week-Numbering Year Helpers * @summary Get the number of calendar ISO week-numbering years between the given dates. * * @description * Get the number of calendar ISO week-numbering years between the given dates. * * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date * * @param {Date|String|Number} dateLeft - the later date * @param {Date|String|Number} dateRight - the earlier date * @returns {Number} the number of calendar ISO week-numbering years * * @example * // How many calendar ISO week-numbering years are 1 January 2010 and 1 January 2012? * var result = differenceInCalendarISOYears( * new Date(2012, 0, 1), * new Date(2010, 0, 1) * ) * //=> 2 */ function differenceInCalendarISOYears (dirtyDateLeft, dirtyDateRight) { return get_iso_year(dirtyDateLeft) - get_iso_year(dirtyDateRight) } var difference_in_calendar_iso_years = differenceInCalendarISOYears; /** * @category Month Helpers * @summary Get the number of calendar months between the given dates. * * @description * Get the number of calendar months between the given dates. * * @param {Date|String|Number} dateLeft - the later date * @param {Date|String|Number} dateRight - the earlier date * @returns {Number} the number of calendar months * * @example * // How many calendar months are between 31 January 2014 and 1 September 2014? * var result = differenceInCalendarMonths( * new Date(2014, 8, 1), * new Date(2014, 0, 31) * ) * //=> 8 */ function differenceInCalendarMonths (dirtyDateLeft, dirtyDateRight) { var dateLeft = parse_1(dirtyDateLeft); var dateRight = parse_1(dirtyDateRight); var yearDiff = dateLeft.getFullYear() - dateRight.getFullYear(); var monthDiff = dateLeft.getMonth() - dateRight.getMonth(); return yearDiff * 12 + monthDiff } var difference_in_calendar_months = differenceInCalendarMonths; /** * @category Quarter Helpers * @summary Get the year quarter of the given date. * * @description * Get the year quarter of the given date. * * @param {Date|String|Number} date - the given date * @returns {Number} the quarter * * @example * // Which quarter is 2 July 2014? * var result = getQuarter(new Date(2014, 6, 2)) * //=> 3 */ function getQuarter (dirtyDate) { var date = parse_1(dirtyDate); var quarter = Math.floor(date.getMonth() / 3) + 1; return quarter } var get_quarter = getQuarter; /** * @category Quarter Helpers * @summary Get the number of calendar quarters between the given dates. * * @description * Get the number of calendar quarters between the given dates. * * @param {Date|String|Number} dateLeft - the later date * @param {Date|String|Number} dateRight - the earlier date * @returns {Number} the number of calendar quarters * * @example * // How many calendar quarters are between 31 December 2013 and 2 July 2014? * var result = differenceInCalendarQuarters( * new Date(2014, 6, 2), * new Date(2013, 11, 31) * ) * //=> 3 */ function differenceInCalendarQuarters (dirtyDateLeft, dirtyDateRight) { var dateLeft = parse_1(dirtyDateLeft); var dateRight = parse_1(dirtyDateRight); var yearDiff = dateLeft.getFullYear() - dateRight.getFullYear(); var quarterDiff = get_quarter(dateLeft) - get_quarter(dateRight); return yearDiff * 4 + quarterDiff } var difference_in_calendar_quarters = differenceInCalendarQuarters; var MILLISECONDS_IN_MINUTE$5 = 60000; var MILLISECONDS_IN_WEEK$1 = 604800000; /** * @category Week Helpers * @summary Get the number of calendar weeks between the given dates. * * @description * Get the number of calendar weeks between the given dates. * * @param {Date|String|Number} dateLeft - the later date * @param {Date|String|Number} dateRight - the earlier date * @param {Object} [options] - the object with options * @param {Number} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday) * @returns {Number} the number of calendar weeks * * @example * // How many calendar weeks are between 5 July 2014 and 20 July 2014? * var result = differenceInCalendarWeeks( * new Date(2014, 6, 20), * new Date(2014, 6, 5) * ) * //=> 3 * * @example * // If the week starts on Monday, * // how many calendar weeks are between 5 July 2014 and 20 July 2014? * var result = differenceInCalendarWeeks( * new Date(2014, 6, 20), * new Date(2014, 6, 5), * {weekStartsOn: 1} * ) * //=> 2 */ function differenceInCalendarWeeks (dirtyDateLeft, dirtyDateRight, dirtyOptions) { var startOfWeekLeft = start_of_week(dirtyDateLeft, dirtyOptions); var startOfWeekRight = start_of_week(dirtyDateRight, dirtyOptions); var timestampLeft = startOfWeekLeft.getTime() - startOfWeekLeft.getTimezoneOffset() * MILLISECONDS_IN_MINUTE$5; var timestampRight = startOfWeekRight.getTime() - startOfWeekRight.getTimezoneOffset() * MILLISECONDS_IN_MINUTE$5; // Round the number of days to the nearest integer // because the number of milliseconds in a week is not constant // (e.g. it's different in the week of the daylight saving time clock shift) return Math.round((timestampLeft - timestampRight) / MILLISECONDS_IN_WEEK$1) } var difference_in_calendar_weeks = differenceInCalendarWeeks; /** * @category Year Helpers * @summary Get the number of calendar years between the given dates. * * @description * Get the number of calendar years between the given dates. * * @param {Date|String|Number} dateLeft - the later date * @param {Date|String|Number} dateRight - the earlier date * @returns {Number} the number of calendar years * * @example * // How many calendar years are between 31 December 2013 and 11 February 2015? * var result = differenceInCalendarYears( * new Date(2015, 1, 11), * new Date(2013, 11, 31) * ) * //=> 2 */ function differenceInCalendarYears (dirtyDateLeft, dirtyDateRight) { var dateLeft = parse_1(dirtyDateLeft); var dateRight = parse_1(dirtyDateRight); return dateLeft.getFullYear() - dateRight.getFullYear() } var difference_in_calendar_years = differenceInCalendarYears; /** * @category Day Helpers * @summary Get the number of full days between the given dates. * * @description * Get the number of full days between the given dates. * * @param {Date|String|Number} dateLeft - the later date * @param {Date|String|Number} dateRight - the earlier date * @returns {Number} the number of full days * * @example * // How many full days are between * // 2 July 2011 23:00:00 and 2 July 2012 00:00:00? * var result = differenceInDays( * new Date(2012, 6, 2, 0, 0), * new Date(2011, 6, 2, 23, 0) * ) * //=> 365 */ function differenceInDays (dirtyDateLeft, dirtyDateRight) { var dateLeft = parse_1(dirtyDateLeft); var dateRight = parse_1(dirtyDateRight); var sign = compare_asc(dateLeft, dateRight); var difference = Math.abs(difference_in_calendar_days(dateLeft, dateRight)); dateLeft.setDate(dateLeft.getDate() - sign * difference); // Math.abs(diff in full days - diff in calendar days) === 1 if last calendar day is not full // If so, result must be decreased by 1 in absolute value var isLastDayNotFull = compare_asc(dateLeft, dateRight) === -sign; return sign * (difference - isLastDayNotFull) } var difference_in_days = differenceInDays; /** * @category Millisecond Helpers * @summary Get the number of milliseconds between the given dates. * * @description * Get the number of milliseconds between the given dates. * * @param {Date|String|Number} dateLeft - the later date * @param {Date|String|Number} dateRight - the earlier date * @returns {Number} the number of milliseconds * * @example * // How many milliseconds are between * // 2 July 2014 12:30:20.600 and 2 July 2014 12:30:21.700? * var result = differenceInMilliseconds( * new Date(2014, 6, 2, 12, 30, 21, 700), * new Date(2014, 6, 2, 12, 30, 20, 600) * ) * //=> 1100 */ function differenceInMilliseconds (dirtyDateLeft, dirtyDateRight) { var dateLeft = parse_1(dirtyDateLeft); var dateRight = parse_1(dirtyDateRight); return dateLeft.getTime() - dateRight.getTime() } var difference_in_milliseconds = differenceInMilliseconds; var MILLISECONDS_IN_HOUR$2 = 3600000; /** * @category Hour Helpers * @summary Get the number of hours between the given dates. * * @description * Get the number of hours between the given dates. * * @param {Date|String|Number} dateLeft - the later date * @param {Date|String|Number} dateRight - the earlier date * @returns {Number} the number of hours * * @example * // How many hours are between 2 July 2014 06:50:00 and 2 July 2014 19:00:00? * var result = differenceInHours( * new Date(2014, 6, 2, 19, 0), * new Date(2014, 6, 2, 6, 50) * ) * //=> 12 */ function differenceInHours (dirtyDateLeft, dirtyDateRight) { var diff = difference_in_milliseconds(dirtyDateLeft, dirtyDateRight) / MILLISECONDS_IN_HOUR$2; return diff > 0 ? Math.floor(diff) : Math.ceil(diff) } var difference_in_hours = differenceInHours; /** * @category ISO Week-Numbering Year Helpers * @summary Subtract the specified number of ISO week-numbering years from the given date. * * @description * Subtract the specified number of ISO week-numbering years from the given date. * * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date * * @param {Date|String|Number} date - the date to be changed * @param {Number} amount - the amount of ISO week-numbering years to be subtracted * @returns {Date} the new date with the ISO week-numbering years subtracted * * @example * // Subtract 5 ISO week-numbering years from 1 September 2014: * var result = subISOYears(new Date(2014, 8, 1), 5) * //=> Mon Aug 31 2009 00:00:00 */ function subISOYears (dirtyDate, dirtyAmount) { var amount = Number(dirtyAmount); return add_iso_years(dirtyDate, -amount) } var sub_iso_years = subISOYears; /** * @category ISO Week-Numbering Year Helpers * @summary Get the number of full ISO week-numbering years between the given dates. * * @description * Get the number of full ISO week-numbering years between the given dates. * * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date * * @param {Date|String|Number} dateLeft - the later date * @param {Date|String|Number} dateRight - the earlier date * @returns {Number} the number of full ISO week-numbering years * * @example * // How many full ISO week-numbering years are between 1 January 2010 and 1 January 2012? * var result = differenceInISOYears( * new Date(2012, 0, 1), * new Date(2010, 0, 1) * ) * //=> 1 */ function differenceInISOYears (dirtyDateLeft, dirtyDateRight) { var dateLeft = parse_1(dirtyDateLeft); var dateRight = parse_1(dirtyDateRight); var sign = compare_asc(dateLeft, dateRight); var difference = Math.abs(difference_in_calendar_iso_years(dateLeft, dateRight)); dateLeft = sub_iso_years(dateLeft, sign * difference); // Math.abs(diff in full ISO years - diff in calendar ISO years) === 1 // if last calendar ISO year is not full // If so, result must be decreased by 1 in absolute value var isLastISOYearNotFull = compare_asc(dateLeft, dateRight) === -sign; return sign * (difference - isLastISOYearNotFull) } var difference_in_iso_years = differenceInISOYears; var MILLISECONDS_IN_MINUTE$6 = 60000; /** * @category Minute Helpers * @summary Get the number of minutes between the given dates. * * @description * Get the number of minutes between the given dates. * * @param {Date|String|Number} dateLeft - the later date * @param {Date|String|Number} dateRight - the earlier date * @returns {Number} the number of minutes * * @example * // How many minutes are between 2 July 2014 12:07:59 and 2 July 2014 12:20:00? * var result = differenceInMinutes( * new Date(2014, 6, 2, 12, 20, 0), * new Date(2014, 6, 2, 12, 7, 59) * ) * //=> 12 */ function differenceInMinutes (dirtyDateLeft, dirtyDateRight) { var diff = difference_in_milliseconds(dirtyDateLeft, dirtyDateRight) / MILLISECONDS_IN_MINUTE$6; return diff > 0 ? Math.floor(diff) : Math.ceil(diff) } var difference_in_minutes = differenceInMinutes; /** * @category Month Helpers * @summary Get the number of full months between the given dates. * * @description * Get the number of full months between the given dates. * * @param {Date|String|Number} dateLeft - the later date * @param {Date|String|Number} dateRight - the earlier date * @returns {Number} the number of ful