UNPKG

@naturalcycles/js-lib

Version:

Standard library for universal (browser + Node.js) javascript

81 lines (80 loc) 2.43 kB
import { localDate } from './localDate'; /** * Class that supports ISO8601 "Time interval" standard that looks like `2022-02-24/2022-03-30`. * * @experimental */ export class DateInterval { constructor(start, end) { this.start = start; this.end = end; } static of(start, end) { return new DateInterval(localDate(start), localDate(end)); } /** * Parses string like `2022-02-24/2023-03-30` into a DateInterval. */ static parse(d) { if (d instanceof DateInterval) return d; const [start, end] = d.split('/'); if (!end || !start) { throw new Error(`Cannot parse "${d}" into DateInterval`); } return new DateInterval(localDate(start), localDate(end)); } isSame(d) { return this.cmp(d) === 0; } isBefore(d, inclusive = false) { const r = this.cmp(d); return r === -1 || (r === 0 && inclusive); } isSameOrBefore(d) { return this.cmp(d) <= 0; } isAfter(d, inclusive = false) { const r = this.cmp(d); return r === 1 || (r === 0 && inclusive); } isSameOrAfter(d) { return this.cmp(d) >= 0; } /** * Ranges of DateInterval (start, end) are INCLUSIVE. */ includes(d, incl = '[]') { d = localDate(d); // eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with return d.isAfter(this.start, incl[0] === '[') && d.isBefore(this.end, incl[1] === ']'); } intersects(int, inclusive = true) { const $int = DateInterval.parse(int); const incl = inclusive ? '[]' : '()'; return this.includes($int.start, incl) || this.includes($int.end, incl); } /** * DateIntervals compare by start date. * If it's the same - then by end date. */ cmp(d) { d = DateInterval.parse(d); return this.start.compare(d.start) || this.end.compare(d.end); } getDays(incl = '[]') { return localDate.range(this.start, this.end, incl, 1, 'day'); } /** * Returns an array of LocalDates that are included in the interval. */ range(incl = '[]', step = 1, stepUnit = 'day') { return localDate.range(this.start, this.end, incl, step, stepUnit); } toString() { return [this.start, this.end].join('/'); } toJSON() { return this.toString(); } }