calendar-date
Version:
Immutable object to represent a calendar date with zero dependencies
123 lines (122 loc) • 4.92 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.CalendarDateRange = void 0;
const CalendarDate_1 = require("./CalendarDate");
class CalendarDateRange {
constructor(start, end, autoArrange = false) {
if (!autoArrange && end < start) {
throw new Error("CalendarDateRange Validation Error: end date can't be before the start date.");
}
this.start = start <= end ? start : end;
this.end = end > start ? end : start;
Object.freeze(this);
}
equals(calendarDateRange) {
return this.start.equals(calendarDateRange.start) && this.end.equals(calendarDateRange.end);
}
toString() {
return `${this.start.toString()}/${this.end.toString()}`;
}
toJSON() {
return this.toString();
}
/**
* @param isoString pattern YYYY-MM-DD/YYYY-MM-DD
*/
static parse(isoString) {
const split = isoString.split('/');
if (split.length !== 2) {
throw new Error(`CalendarDateRange Validation Error: Input ${isoString.toString()} is not valid, it should follow the pattern YYYY-MM-DD/YYYY-MM-DD.`);
}
return new CalendarDateRange(new CalendarDate_1.CalendarDate(split[0]), new CalendarDate_1.CalendarDate(split[1]));
}
/**
* Returns true if the given date ranges have gaps.
* The date ranges will be sorted.
*/
static hasGaps(values, options) {
const sortedValues = values.sort((a, b) => a.start.valueOf() - b.start.valueOf());
for (let i = 1; i < sortedValues.length; i++) {
let differenceInDays = sortedValues[i].start.getDifferenceInDays(sortedValues[i - 1].end);
if (options === null || options === void 0 ? void 0 : options.excludeStart) {
differenceInDays += 1;
}
if (options === null || options === void 0 ? void 0 : options.excludeEnd) {
differenceInDays += 1;
}
if (differenceInDays > 1) {
return true;
}
}
return false;
}
/**
* Returns true if the given date ranges overlap.
* The date ranges will be sorted.
*/
static hasOverlap(values, options) {
const sortedValues = values.sort((a, b) => a.start.valueOf() - b.start.valueOf());
for (let i = 1; i < sortedValues.length; i++) {
let differenceInDays = sortedValues[i].start.getDifferenceInDays(sortedValues[i - 1].end);
if (options === null || options === void 0 ? void 0 : options.excludeStart) {
differenceInDays += 1;
}
if (options === null || options === void 0 ? void 0 : options.excludeEnd) {
differenceInDays += 1;
}
if (differenceInDays <= 0) {
return true;
}
}
return false;
}
/**
* Returns the total amount of days in included in this date range
* including start and end day.
*/
getTotalDays() {
return this.end.getDifferenceInDays(this.start) + 1;
}
/**
* Returns the difference in days between the start and end date.
* See documentation of CalendarDate.getDifferenceInDays for more information.
*/
getDifferenceInDays() {
return this.end.getDifferenceInDays(this.start);
}
/**
* Returns the difference in months as an integer, ignoring the day values.
*/
getDifferenceInMonths() {
return (this.end.year - this.start.year) * 12 + (this.end.month - this.start.month);
}
includes(input, options) {
if (input instanceof CalendarDateRange) {
return this.includes(input.start, options) && this.includes(input.end, options);
}
return (((options === null || options === void 0 ? void 0 : options.excludeStart) ? input > this.start : input >= this.start) &&
((options === null || options === void 0 ? void 0 : options.excludeEnd) ? input < this.end : input <= this.end));
}
/**
* Creates an iterator that yields each CalendarDate in the range from start to end (inclusive).
*/
*iterateDatesInRange(options) {
let current = this.start;
// Skip start date if excludeStart is true
if (options === null || options === void 0 ? void 0 : options.excludeStart) {
current = current.addDays(1);
}
const endDate = (options === null || options === void 0 ? void 0 : options.excludeEnd) ? this.end.addDays(-1) : this.end;
while (current <= endDate) {
yield current;
current = current.addDays(1);
}
}
/**
* Returns an array of all CalendarDate objects in the range.
*/
toDatesArrayInRange(options) {
return Array.from(this.iterateDatesInRange(options));
}
}
exports.CalendarDateRange = CalendarDateRange;