UNPKG

@oxog/kairos

Version:

Revolutionary zero-dependency JavaScript date/time library with modular architecture and dynamic holiday system

311 lines 10.2 kB
export class DateRange { constructor(start, end, unit = 'day', step = 1) { this.start = new Date(start); this.end = new Date(end); this.unit = unit; this.step = step; } *[Symbol.iterator]() { let current = new Date(this.start); while (current <= this.end) { yield new Date(current); current = this.addUnit(current, this.unit, this.step); } } toArray() { return Array.from(this); } map(callback) { const result = []; let index = 0; for (const date of this) { result.push(callback(date, index++)); } return result; } filter(callback) { const result = []; let index = 0; for (const date of this) { if (callback(date, index++)) { result.push(date); } } return result; } find(callback) { let index = 0; for (const date of this) { if (callback(date, index++)) { return date; } } return undefined; } every(callback) { let index = 0; for (const date of this) { if (!callback(date, index++)) { return false; } } return true; } some(callback) { let index = 0; for (const date of this) { if (callback(date, index++)) { return true; } } return false; } reduce(callback, initialValue) { let accumulator = initialValue; let index = 0; for (const date of this) { accumulator = callback(accumulator, date, index++); } return accumulator; } count() { let count = 0; for (const _ of this) { count++; } return count; } businessDays() { return this.filter((date) => { const day = date.getDay(); return day !== 0 && day !== 6; }); } weekends() { return this.filter((date) => { const day = date.getDay(); return day === 0 || day === 6; }); } weekday(weekday) { return this.filter((date) => date.getDay() === weekday); } month(month) { return this.filter((date) => date.getMonth() === month - 1); } year(year) { return this.filter((date) => date.getFullYear() === year); } chunk(size) { const dates = this.toArray(); const chunks = []; for (let i = 0; i < dates.length; i += size) { const chunkDates = dates.slice(i, i + size); if (chunkDates.length > 0) { chunks.push(new DateRange(chunkDates[0], chunkDates[chunkDates.length - 1], this.unit, this.step)); } } return chunks; } includes(date) { return date >= this.start && date <= this.end; } contains(date) { return this.includes(date); } getStart() { return new Date(this.start); } getEnd() { return new Date(this.end); } overlaps(other) { return this.start <= other.end && this.end >= other.start; } intersection(other) { const start = new Date(Math.max(this.start.getTime(), other.start.getTime())); const end = new Date(Math.min(this.end.getTime(), other.end.getTime())); if (start <= end) { return new DateRange(start, end, this.unit, this.step); } return null; } union(other) { if (this.overlaps(other) || this.isAdjacent(other)) { const start = new Date(Math.min(this.start.getTime(), other.start.getTime())); const end = new Date(Math.max(this.end.getTime(), other.end.getTime())); return new DateRange(start, end, this.unit, this.step); } return null; } isAdjacent(other) { const nextDay = new Date(this.end); nextDay.setDate(nextDay.getDate() + 1); const prevDay = new Date(this.start); prevDay.setDate(prevDay.getDate() - 1); return nextDay.getTime() === other.start.getTime() || prevDay.getTime() === other.end.getTime(); } duration() { return this.end.getTime() - this.start.getTime(); } durationIn(unit) { const ms = this.duration(); switch (unit) { case 'millisecond': case 'milliseconds': case 'ms': return ms; case 'second': case 'seconds': case 's': return ms / 1000; case 'minute': case 'minutes': case 'm': return ms / (1000 * 60); case 'hour': case 'hours': case 'h': return ms / (1000 * 60 * 60); case 'day': case 'days': case 'd': return ms / (1000 * 60 * 60 * 24); case 'week': case 'weeks': case 'w': return ms / (1000 * 60 * 60 * 24 * 7); case 'month': case 'months': case 'M': return ms / (1000 * 60 * 60 * 24 * 30.44); case 'year': case 'years': case 'y': return ms / (1000 * 60 * 60 * 24 * 365.25); default: return ms; } } addUnit(date, unit, amount) { const result = new Date(date); switch (unit) { case 'year': case 'years': case 'y': result.setFullYear(result.getFullYear() + amount); break; case 'month': case 'months': case 'M': result.setMonth(result.getMonth() + amount); break; case 'week': case 'weeks': case 'w': result.setDate(result.getDate() + amount * 7); break; case 'day': case 'days': case 'd': result.setDate(result.getDate() + amount); break; case 'hour': case 'hours': case 'h': result.setHours(result.getHours() + amount); break; case 'minute': case 'minutes': case 'm': result.setMinutes(result.getMinutes() + amount); break; case 'second': case 'seconds': case 's': result.setSeconds(result.getSeconds() + amount); break; case 'millisecond': case 'milliseconds': case 'ms': result.setMilliseconds(result.getMilliseconds() + amount); break; } return result; } } export default { name: 'range', version: '1.0.0', size: 3072, install(kairos) { kairos.extend({ range(end, unit = 'day', step = 1) { return new DateRange(this.toDate(), end.toDate(), unit, step); }, until(end, unit = 'day') { return new DateRange(this.toDate(), end.toDate(), unit).toArray(); }, since(start, unit = 'day') { return new DateRange(start.toDate(), this.toDate(), unit).toArray(); }, datesInMonth() { const start = this.clone().date(1); const end = this.clone().add(1, 'month').date(1).subtract(1, 'day'); return new DateRange(start.toDate(), end.toDate()).toArray(); }, datesInYear() { const start = this.clone().month(1).date(1); const end = this.clone().add(1, 'year').month(1).date(1).subtract(1, 'day'); return new DateRange(start.toDate(), end.toDate()).toArray(); }, businessDaysInCurrentMonth() { const start = this.clone().date(1); const end = this.clone().add(1, 'month').date(1).subtract(1, 'day'); return new DateRange(start.toDate(), end.toDate()).businessDays(); }, rangeFor(amount, unit) { const end = this.add(amount, unit); return new DateRange(this.toDate(), end.toDate()); }, businessDaysUntil(end) { return new DateRange(this.toDate(), end.toDate()).businessDays(); }, datesInWeek() { const currentDay = this.day(); const startOfWeek = this.clone().subtract(currentDay, 'days'); const endOfWeek = startOfWeek.clone().add(6, 'days'); return new DateRange(startOfWeek.toDate(), endOfWeek.toDate()).toArray(); }, }); kairos.addStatic?.({ range(start, end, unit = 'day', step = 1) { const startDate = kairos(start); const endDate = kairos(end); return new DateRange(startDate.toDate(), endDate.toDate(), unit, step); }, monthRange(year, month) { const start = new Date(year, month - 1, 1); const end = new Date(year, month, 0); return new DateRange(start, end); }, yearRange(year) { const start = new Date(year, 0, 1); const end = new Date(year, 11, 31); return new DateRange(start, end); }, next(amount, unit) { const start = new Date(); const end = kairos(start).add(amount, unit).toDate(); return new DateRange(start, end); }, previous(amount, unit) { const end = new Date(); const start = kairos(end).subtract(amount, unit).toDate(); return new DateRange(start, end); }, createRange: (start, end, unit, step) => new DateRange(start, end, unit, step), }); }, }; //# sourceMappingURL=range.js.map