Skip to content

Repository files navigation

easy-date-range

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.

Installation

npm install easy-date-range luxon

luxon is a peer dependency. easy-date-range accepts JavaScript Date objects and Luxon DateTime objects as inputs, and returns Luxon DateTime objects by default.

Quick Start

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();

Public API

The root package exports:

import{DateRange,RANGE_TYPE,WEEKDAY,chunkMonthExtended,typeOptionsDays,typeOptionsMonthExact,typeOptionsMonthExtended,typeOptionsWeek,}from"easy-date-range";

DateRange

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.

Options

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:

OptionTypeDefaultDescription
refDateDateTime | Datecurrent date/timeReference date used to calculate the range.
startOffsetnumber0Integer offset applied to the beginning of the range.
endOffsetnumber0Integer offset applied to the end of the range.

Method-specific options:

MethodOptionTypeDefault
getDaysdaysCountpositive integer1
getWeekrefWeekdayWEEKDAY / 1..7WEEKDAY.Monday
getMonthExtendedrefWeekdayWEEKDAY / 1..7WEEKDAY.Monday

Offsets

Offsets are integer day adjustments applied after the base range is generated.

  • Positive startOffset adds dates before the range.
  • Negative startOffset removes dates from the beginning.
  • Positive endOffset adds dates after the range.
  • Negative endOffset removes dates from the end.

Negative offsets cannot remove the whole range.

constrange=newDateRange().getMonthExact({refDate: newDate("2026-05-14"),startOffset: 2,endOffset: -2,});

Recipes

Current Week

constcurrentWeek=newDateRange().getWeek();

Sunday-First Week

constsundayFirst=newDateRange().getWeek({refWeekday: WEEKDAY.Sunday,});

Exact Month

constmay=newDateRange().getMonthExact({refDate: newDate("2026-05-14"),});

Month Grid

Use getMonthExtended() for calendar grids that need complete weeks.

constmonthGridRange=newDateRange().getMonthExtended({refDate: newDate("2026-05-14"),refWeekday: WEEKDAY.Monday,});

Month Chunks

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,});

Previous And Next Ranges

constcurrent=newDateRange().getWeek({refDate: newDate("2026-05-14"),});constprevious=newDateRange().getPrevious(current);constnext=newDateRange().getNext(current);

Worklist Buckets

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()),);

Limitations

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 DateTime behavior.

For full scheduling and resource planning, use a dedicated calendar/scheduler library and treat easy-date-range as a small helper for date projections.

v2 Migration Notes

easy-date-range@2.0.0 contains intentional breaking changes:

  • dateTimes and toDateTimes() 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; daysCount must be at least 1.
  • @types/luxon is installed as a package dependency so generated declaration files can reference Luxon types correctly.

Development

npm run test:run
npm run coverage
npm run lint
npm run build
npm run smoke:pack

smoke:pack builds the package, checks the dry-run npm package contents and verifies both ESM and CJS runtime imports.

About

No description, website, or topics provided.

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages