@naturalcycles/js-lib
Version:
Standard library for universal (browser + Node.js) javascript
80 lines (79 loc) • 2.2 kB
JavaScript
import { localDate } from './localDate.js';
/**
* Class that supports ISO8601 "Time interval" standard that looks like `2022-02-24/2022-03-30`.
*
* @experimental
*/
export class DateInterval {
start;
end;
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) {
return localDate(d).isBetween(this.start, this.end, '[]');
}
intersects(int) {
const $int = DateInterval.parse(int);
return this.includes($int.start) || this.includes($int.end);
}
/**
* 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() {
return localDate.range(this.start, this.end, '[]', 1, 'day');
}
/**
* Returns an array of LocalDates that are included in the interval.
*/
range(step = 1, stepUnit = 'day') {
return localDate.range(this.start, this.end, '[]', step, stepUnit);
}
toString() {
return [this.start, this.end].join('/');
}
toJSON() {
return this.toString();
}
}