Small TypeScript library for generating calendar-friendly date ranges: days, weeks, exact months and months extended to full weeks.
The library is intentionally narrow. It is useful as a foundation for simple calendar views, worklists, dashboards and date grouping. It is not a booking engine, recurrence engine or full scheduler.
npm install easy-date-range luxonluxon is a peer dependency. easy-date-range accepts JavaScript Date
objects and Luxon DateTime objects as inputs, and returns Luxon DateTime
objects by default.
import{DateRange,WEEKDAY}from"easy-date-range";constweek=newDateRange().getWeek({refDate: newDate("2026-05-14"),refWeekday: WEEKDAY.Monday,});week.dateTimes.forEach((dateTime)=>{console.log(dateTime.toISODate());});Use toDates() when JavaScript Date objects are needed:
constjsDates=week.toDates();The root package exports:
import{DateRange,RANGE_TYPE,WEEKDAY,chunkMonthExtended,typeOptionsDays,typeOptionsMonthExact,typeOptionsMonthExtended,typeOptionsWeek,}from"easy-date-range";Create an instance and initialize it with one range generator:
newDateRange().getDays(options);newDateRange().getWeek(options);newDateRange().getMonthExact(options);newDateRange().getMonthExtended(options);newDateRange().getNext(dateRange);newDateRange().getPrevious(dateRange);After initialization, the instance exposes:
dateRange.dateTimes;// readonly DateTime[]dateRange.toDateTimes();// readonly DateTime[]dateRange.toDates();// Date[]dateRange.refDate;dateRange.refWeekday;dateRange.startOffset;dateRange.endOffset;dateRange.daysCount;dateRange.rangeType;dateRange.isNext;dateRange.isPrevious;dateTimes and toDateTimes() return readonly copies. Mutating the returned
array does not mutate the DateRange instance.
All range generators accept an optional object. Passing {} is valid and uses
defaults. Unknown option properties throw a runtime error, which helps catch
misspellings in JavaScript code.
Common options:
| Option | Type | Default | Description |
|---|---|---|---|
refDate | DateTime | Date | current date/time | Reference date used to calculate the range. |
startOffset | number | 0 | Integer offset applied to the beginning of the range. |
endOffset | number | 0 | Integer offset applied to the end of the range. |
Method-specific options:
| Method | Option | Type | Default |
|---|---|---|---|
getDays | daysCount | positive integer | 1 |
getWeek | refWeekday | WEEKDAY / 1..7 | WEEKDAY.Monday |
getMonthExtended | refWeekday | WEEKDAY / 1..7 | WEEKDAY.Monday |
Offsets are integer day adjustments applied after the base range is generated.
- Positive
startOffsetadds dates before the range. - Negative
startOffsetremoves dates from the beginning. - Positive
endOffsetadds dates after the range. - Negative
endOffsetremoves dates from the end.
Negative offsets cannot remove the whole range.
constrange=newDateRange().getMonthExact({refDate: newDate("2026-05-14"),startOffset: 2,endOffset: -2,});constcurrentWeek=newDateRange().getWeek();constsundayFirst=newDateRange().getWeek({refWeekday: WEEKDAY.Sunday,});constmay=newDateRange().getMonthExact({refDate: newDate("2026-05-14"),});Use getMonthExtended() for calendar grids that need complete weeks.
constmonthGridRange=newDateRange().getMonthExtended({refDate: newDate("2026-05-14"),refWeekday: WEEKDAY.Monday,});chunkMonthExtended() splits a month-extended range into week rows.
constrange=newDateRange().getMonthExtended({refDate: newDate("2026-05-14"),});constweeks=chunkMonthExtended(range);Set nullNextPrevDates to replace dates outside the reference month with
null.
constweeks=chunkMonthExtended(range,{nullNextPrevDates: true,});constcurrent=newDateRange().getWeek({refDate: newDate("2026-05-14"),});constprevious=newDateRange().getPrevious(current);constnext=newDateRange().getNext(current);Use ranges to group tasks, reviews or deadlines into simple operational buckets.
import{DateTime}from"luxon";consttasks=[{title: "Review procedure",dueDate: DateTime.fromISO("2026-05-14")},{title: "Approve record",dueDate: DateTime.fromISO("2026-05-20")},];constthisWeek=newDateRange().getWeek({refDate: DateTime.now(),});constthisWeekMillis=newSet(thisWeek.dateTimes.map((dateTime)=>dateTime.toMillis()),);constdueThisWeek=tasks.filter((task)=>thisWeekMillis.has(task.dueDate.startOf("day").toMillis()),);easy-date-range does not provide:
- recurrence rules;
- event storage;
- booking or reservation conflict detection;
- resource availability;
- drag-and-drop scheduler UI;
- timezone policy beyond Luxon
DateTimebehavior.
For full scheduling and resource planning, use a dedicated calendar/scheduler
library and treat easy-date-range as a small helper for date projections.
easy-date-range@2.0.0 contains intentional breaking changes:
dateTimesandtoDateTimes()return readonly array copies.- Unknown properties in range generator options now throw runtime errors.
- Empty
{}options are valid and use defaults. getDays({ daysCount: 0 })is invalid;daysCountmust be at least1.@types/luxonis installed as a package dependency so generated declaration files can reference Luxon types correctly.
npm run test:run
npm run coverage
npm run lint
npm run build
npm run smoke:packsmoke:pack builds the package, checks the dry-run npm package contents and
verifies both ESM and CJS runtime imports.