@philiprehberger/date-range-ts
v0.3.0
Published
Date range operations — overlap, gap, iterate, merge
Readme
@philiprehberger/date-range-ts

Date range operations — overlap, gap, iterate, merge, recurring, blackout, business days, shift
Installation
npm install @philiprehberger/date-range-tsUsage
import { dateRange, mergeRanges } from '@philiprehberger/date-range-ts';
const booking = dateRange('2026-03-15', '2026-03-20');
const request = dateRange('2026-03-18', '2026-03-25');
booking.overlaps(request); // true
booking.intersection(request); // March 18-20
booking.durationIn('days'); // 5
for (const day of booking.iterate('day')) { /* ... */ }
mergeRanges([range1, range2, range3]); // merged, non-overlappingRecurring Ranges
Generate repeating date ranges from a pattern:
const meeting = dateRange('2026-04-06', '2026-04-06');
// Weekly recurrence, 4 occurrences
const weeklies = meeting.recurring('weekly', 4);
// [Apr 6, Apr 13, Apr 20, Apr 27]
// Monthly recurrence
const monthlies = meeting.recurring('monthly', 3);
// [Apr 6, May 6, Jun 6]Blackout Periods
Skip specific dates or ranges during iteration:
const sprint = dateRange('2026-04-01', '2026-04-10');
// Exclude specific dates
const holidays = ['2026-04-03', '2026-04-07'];
for (const day of sprint.excludeDates(holidays).iterate('day')) {
// skips Apr 3 and Apr 7
}
// Exclude entire ranges
const vacation = dateRange('2026-04-05', '2026-04-06');
for (const day of sprint.excludeRanges([vacation]).iterate('day')) {
// skips Apr 5-6
}Business Day Support
Count and iterate only weekdays (Mon-Fri):
const week = dateRange('2026-03-23', '2026-03-29'); // Mon-Sun
week.businessDays(); // 5
for (const day of week.iterateBusinessDays()) {
// yields Mon, Tue, Wed, Thu, Fri only
}Clamp to Window
Trim a range to fit within a bounding window:
const reportPeriod = dateRange('2026-03-01', '2026-03-31');
const fiscalQuarter = dateRange('2026-03-15', '2026-06-15');
const visible = reportPeriod.clamp(fiscalQuarter);
// Mar 15 - Mar 31
// Object-literal bounds also work
const trimmed = reportPeriod.clamp({ start: '2026-03-10', end: '2026-03-20' });
// Mar 10 - Mar 20
// Disjoint ranges return null
const disjoint = reportPeriod.clamp(dateRange('2026-05-01', '2026-05-10'));
// nullRange Shifting
Move an entire range forward or backward:
const event = dateRange('2026-03-15', '2026-03-20');
const postponed = event.shift({ days: 7 });
// Mar 22 - Mar 27
const earlier = event.shift({ days: -3 });
// Mar 12 - Mar 17
const nextMonth = event.shift({ months: 1 });
// Apr 15 - Apr 20API
| Method | Description |
|--------|-------------|
| dateRange(start, end) | Create a date range |
| .overlaps(other) | Check if ranges overlap |
| .contains(date) / .containsRange(other) | Containment checks |
| .intersection(other) | Overlapping portion |
| clamp(bounds) | Trim range to the bounding window; returns null if disjoint |
| .union(other) | Merge two ranges |
| .gap(other) | Gap between ranges |
| .iterate(step) | Generator yielding dates |
| .splitBy(step) | Split into sub-ranges |
| .durationIn(unit) | Duration as number |
| .recurring(pattern, limit) | Generate repeating ranges |
| .excludeDates(dates) | Iterate skipping specific dates |
| .excludeRanges(ranges) | Iterate skipping date ranges |
| .businessDays() | Count weekdays in range |
| .iterateBusinessDays() | Generator yielding weekdays only |
| .shift(duration) | Move range by a duration |
| mergeRanges(ranges[]) | Merge all overlapping |
Development
npm install
npm run build
npm testSupport
If you find this project useful:
