UNPKG

@applicvision/js-toolbox

Version:

A collection of tools for modern JavaScript development

167 lines (157 loc) 5.17 kB
export const YEAR = 'year'; export const MONTH = 'month'; export const DAY = 'day'; export const HOUR = 'hour'; export const MINUTE = 'minute'; export const SECOND = 'second'; export const MILLISECOND = 'millisecond'; export const YEARS = YEAR; export const MONTHS = MONTH; export const DAYS = DAY; export const HOURS = HOUR; export const MINUTES = MINUTE; export const SECONDS = SECOND; export const MILLISECONDS = MILLISECOND; const units = [YEAR, MONTH, DAY, HOUR, MINUTE, SECOND, MILLISECOND] function unitsFrom(unit) { return units.slice(units.indexOf(unit)) } const timeUnits = unitsFrom(HOUR) class IzzaDate extends Date { static get YEAR() { return YEAR }; static get MONTH() { return MONTH }; static get DAY() { return DAY }; static get YEARS() { return YEAR }; static get MONTHS() { return MONTH }; static get DAYS() { return DAY }; /** * Add to a date by given amount in given unit. * @param {number} amount Amont to add * @param {'year'|'month'|'day'|'hour'|'minute'|'second'|'millisecond'} unit Unit to add to * @param {...any} otherChanges Other changes, alternating `amount` and `unit`. * @returns {IzzaDate} */ add(amount, unit, ...otherChanges) { if (amount === undefined && unit === undefined) { return this; } return this .set(unit, this.get(unit) + amount) .add(...otherChanges); } /** * Set the value of a given unit. * @param {'year'|'month'|'day'|'hour'|'minute'|'second'|'millisecond'} unit Unit to set * @param {number} value The new value */ set(unit, value) { switch (unit) { case YEAR: this.setFullYear(value); break; case MONTH: this.setMonth(value); break; case DAY: this.setDate(value); break; case HOUR: this.setHours(value); break case MINUTE: this.setMinutes(value); break case SECOND: this.setSeconds(value); break case MILLISECOND: this.setMilliseconds(value); break } return this; } /** * Get the date's value of a specific unit. * @param {'year'|'month'|'day'|'hour'|'minute'|'second'|'millisecond'} unit Unit to get the value for */ get(unit) { switch (unit) { case YEAR: return this.getFullYear(); case MONTH: return this.getMonth(); case DAY: return this.getDate(); case HOUR: return this.getHours(); case MINUTE: return this.getMinutes(); case SECOND: return this.getSeconds(); case MILLISECOND: return this.getMilliseconds(); } } /** * Subtract from a date by given amounts in given units. * @param {...any} changes Repeating pattern of `amount` and `unit`. */ subtract(...changes) { return this.add(...changes.map((value, index) => index % 2 ? value : -value)); } /** * Same as `.add`, but creates a copy before manipulating the date. * Example: `date.dateByAdding(1, 'year', 2, 'months')` * @param {...any} changes Repeating pattern of `amount` and `unit`. */ dateByAdding(...changes) { return this.copy().add(...changes); } /** * Same as `.set`, but creates a copy before manipulating the date. * @param {'year'|'month'|'day'|'hour'|'minute'|'second'|'millisecond'} unit Unit to set * @param {number} value The new value for the unit */ dateBySetting(unit, value) { return this.copy().set(unit, value); } /** * Returns a copy of the date. */ copy() { return new IzzaDate(this) } /** * Same as `.subtract`, but creates a copy before manupulating the date. * Example: `date.dateBySutracting(1, 'year', 2, 'months')` * @param {...any} changes Repeating patter of `amount` and `unit`. */ dateBySubtracting(...changes) { return this.copy().subtract(...changes); } /** * Checks if the date is earlier in the day than the `compareDate`. * @param {Date} compareDate The date to compare with */ isEarlierInTheDay(compareDate) { return timeUnits.some(unit => this.get(unit) < compareDate.get(unit)) } /** * Checks if the date is same time of day as the `compareDate`. * @param {Date} compareDate The date to compare with */ isSameTimeOfDay(compareDate) { return timeUnits.every(unit => this.get(unit) == compareDate.get(unit)) } /** * Returns object with values for the given units. * @param {('year'|'month'|'day'|'hour'|'minute'|'second'|'millisecond')[]} [forUnits] the units to get the values for */ components(forUnits = units) { return Object.fromEntries(forUnits.map(unit => [unit, this.get(unit)])) } /** * Checks if the date is later in the day than the `compareDate`. * @param {Date} compareDate The date to compare with */ isLaterInTheDay(compareDate) { return timeUnits.some(unit => this.get(unit) > compareDate.get(unit)) } /** * Returns the number of days (integer) until `date`. Returns negative number if `date` is in the past. * @param {Date} date Date to get days until * @returns {number} */ daysUntil(date) { const diff = date - this return Math.floor(diff / (3600 * 1000 * 24)) + this.isLaterInTheDay(date) } /** * Returns the number of days (integer) since `date`. Returns negative number if `date` is in the future. * @param {Date} date Date to get the days since * @returns {number} */ daysSince(date) { return date.daysUntil(this) } } export default IzzaDate;