easy-date-range is a simple, easy to use library for creating date ranges which can be used as a foundation for building all sorts of calendars, schedulers, date lists and more.
easy-date-range simplifies the creation of date ranges by using methods that only need one reference date. The range you get is determined by the method you choose, and the reference date that belongs to it.
Here is a brief summary of core functionalities: the range generators:
getDays
creates a range of custom number of days.getMonthExact
creates a month range, from the first to the last day of the month.getMonthExtended
creates a month range extended to include the full weeks.getWeek
creates a week range.getNext
andgetPrevious
enable easy shifting of any range passed into them.
All range generators use the current day as a reference date unless specified otherwise. It can be easily customized by passing an options
object where you can also set other settings such as offsets, day that starts the week or days count and more.
easy-date-range is written entirely in TypeScript for type safety and other benefits such as autocomplete features in your code editor. Works with no issues in plain JavaScript environment, too.
easy-date-range uses Luxon as a peer dependency for date handling. Luxon is a powerful and modern library for working with dates and times in JavaScript. It offers a consistent and fluent API, as well as support for various formats and locales.
easy-date-range supports both Luxon and native JavaScript dates as inputs and outputs.
At the moment, easy-date-range provides basic functionality for creating date ranges that cover full days. In the future, I plan to add more functions for creating ranges that span other intervals such as minutes, hours or months and years.
To install easy-date-range, run:
npm install easy-date-range luxon
import { DateRange } from 'easy-date-range';
// create a range of current week starting on Monday
const currentWeek = new DateRange().getWeek();
// create a range of a week with specifying reference date
const week = new DateRange().getWeek({ refDate: new Date('2023-01-01') });
Then to access dates array use:
// 'toDateTimes' method for an array of Luxon DateTimes
currentWeek.toDateTimes().forEach((date) => console.log(date.toString()));
// 'toDates' method for an array of JS Dates
currentWeek.toDates().forEach((date) => console.log(date.toString()));
// you can also use a getter property 'dateTimes' for Luxon DateTimes
currentWeek.dateTimes.forEach((dateTime) => console.log(dateTime.toString()));
You can customize the range with an options
object passed to a range generator.
Common options available for all methods:
refDate
for setting the reference date,startOffset
for setting the offset at the start of the range,endOffset
for setting the offset at the end of the range,
Specific options depending on the method and type of range it generates:
refWeekday
for setting the weekday to start the range from. Available withgetWeek
andgetMonthExtended
methodsdaysCount
for setting the number of days withgetDays
method
Note: The offset is applied after the range is created; or in other words, it comes after all other options. Think of it as a way to add or subtract days from your range as a final touch.
Here is a brief example showing how you can customize the range.
// set a month range of January 2023 extended to full weeks with customized refWeekday and offsets
const monthExtended = new DateRange().getMonthExtended({
refDate: new Date('2023-01-01'),
refWeekday: WEEKDAY.Sunday,
startOffset: 2,
endOffset: -2,
});
The range from the above example will include dates that span across all the days of January 2023 extended to start from Friday, Dec 30, 2022 and end on Thursday, Feb 2, 2023.
The first two days in the range come from the startOffset setting, which added two extra days. At the end of the range, two days were removed because of the negative endOffset setting.
Without the offsets, the first day of the range would be Jan 1, 2023 (Sunday - as specified with refWeekday
) and the last day would be Feb 4, 2023 (Saturday).
DateRange is the core component of easy-date-range. It provides various methods and properties for generating and handling date ranges.
To use the class, an instance must be created and initialized with one of the range generator methods.
Property | Type | Default value | Description |
---|---|---|---|
daysCount | number | 0 | The days count value for the range generated by getDays. |
dateTimes | Array<DateTime> | not applicable | The array of luxon DateTimes for current generated range. |
endOffset | number | 0 | The end offset value for current generated range. |
rangeType | RANGE_TYPE | not applicable | The type of current generated range. |
refDate | DateTime | current day | The reference date for current generated range. |
refWeekday | WEEKDAY | 1 | The reference weekday value for current generated range. |
startOffset | number | 0 | The start offset value for current generated range. |
isNext | boolean | false | A boolean that indicates whether DateRange is created with a getNext method. |
isPrevious | boolean | false | A boolean that indicates whether DateRange is created with a getPrevious method. |
Note: All the properties are defined once the date range is initialized, regardless of whether they are relevant for the current range or not.
Method | Description |
---|---|
getDays | Creates a range of custom number of days. |
getMonthExact | Creates a single month range, from the first to the last day of the month. |
getMonthExtended | Creates a single month range extended to include the full weeks. |
getWeek | Creates a single week range. |
getNext | Creates the next range based on given one. |
getPrevious | Creates the previous range based on given one. |
Method | Description |
---|---|
isValidOffset | Checks if a given value is a valid offset. |
isValidRefDate | Checks if a given value is a valid reference date. |
isValidRefWeekday | Checks if a given value is a valid weekday |
Method | Description |
---|---|
toDates | Returns an array of dates generated for the instance as JS Date objects. |
toDateTimes | Returns an array of dates generated for the instance as Luxon DateTime objects. |
Creates a range of custom number of days.
The reference date is a starting point of the range.
The reference date is set to the current day if not specified otherwise.
The length of the range can be specified with the daysCount
property in the options
object. If not specified, the range will be created with a single date.
Each date is set to the start of the day (midnight).
public getDays(options?: OptionsDays): DateRange
Parameter | Type | Description |
---|---|---|
options | OptionsDays | An object to configure the range. |
Options properties
Property | Type | Description |
---|---|---|
refDate | DateTime | Date | The reference date to calculate the range. |
daysCount | number | The number of days to include in the range. |
startOffset | number | The number of days to add or remove from the beginning of the range. |
endOffset | number | The number of days to add or remove from the end of the range. |
// Get a current date
const range1 = new DateRange().getDays();
// Get a range of 10 days starting on 2023-01-10
const range2 = new DateRange().getDays({
daysCount: 10,
refDate: new Date('2023-01-10'),
});
// Generated dates:
// Jan 10, 2023 at 12:00:00 AM
// Jan 11, 2023 at 12:00:00 AM
// Jan 12, 2023 at 12:00:00 AM
// Jan 13, 2023 at 12:00:00 AM
// Jan 14, 2023 at 12:00:00 AM
// Jan 15, 2023 at 12:00:00 AM
// Jan 16, 2023 at 12:00:00 AM
// Jan 17, 2023 at 12:00:00 AM
// Jan 18, 2023 at 12:00:00 AM
// Jan 19, 2023 at 12:00:00 AM
Creates a single month range, from the first to the last day of the month.
The reference date is set to the current day if not specified otherwise.
Each date is set to the start of the day (midnight).
public getMonthExact(options?: OptionsMonthExact): DateRange
Parameter | Type | Description |
---|---|---|
options | OptionsMonthExact | An object to configure the range. |
Options properties
Property | Type | Description |
---|---|---|
refDate | DateTime | Date | The reference date to calculate the range. |
startOffset | number | The number of days to add or remove from the beginning of the range. |
endOffset | number | The number of days to add or remove from the end of the range. |
// Get current month
const currentMonthExact = new DateRange().getMonthExact();
// Get month with specified refDate
const monthExact = new DateRange().getMonthExact({
refDate: new Date('2023-01-10'),
});
// Generated dates:
// Sun, January 1, 2023 at 12:00:00 AM -> The first date of the range
// Mon, January 2, 2023 at 12:00:00 AM
// Tue, January 3, 2023 at 12:00:00 AM
// ...
// Tue, January 31, 2023 at 12:00:00 AM -> The last date of the range
// Get month with specified refDate and offsets
const month3 = new DateRange().getMonthExact({
refDate: new Date('2023-01-10'),
startOffset: 2,
endOffset: 2,
});
// Fri, December 30, 2022 at 12:00:00 AM -> The range starts 2 days before default first day
// Sat, December 31, 2022 at 12:00:00 AM
// Sun, January 1, 2023 at 12:00:00 AM
// ...
// Tue, January 31, 2023 at 12:00:00 AM
// Wed, February 1, 2023 at 12:00:00 AM
// Thu, February 2, 2023 at 12:00:00 AM -> The range ends 2 days after default last day
Creates a single month range extended to include the full weeks.
By default, the method starts the range on Monday before or on the first day of the month and ends it on Sunday after or on the last day of the month.
The end of the week will also be shifted accordingly if the start of the week is changed to a different day than Monday.
The reference date is set to the current day if not specified otherwise.
Each date is set to the start of the day (midnight).
public getMonthExtended(options?: OptionsMonthExtended): DateRange
Parameter | Type | Description |
---|---|---|
options | OptionsMonthExtended | An object to configure the range. |
Options properties
Property | Type | Description |
---|---|---|
refDate | DateTime | Date | The reference date to calculate the range. |
refWeekday | WEEKDAY | The reference weekday to start the range from. |
startOffset | number | The number of days to add or remove from the beginning of the range. |
endOffset | number | The number of days to add or remove from the end of the range. |
// Get current month extended to full weeks
const currentMonthExtended = new DateRange().getMonthExtended();
// Get month extended to full weeks based on a refDate and starting on Wednesday
const monthExtended = new DateRange().getMonthExtended({
refDate: new Date('2023-01-10'),
refWeekday: WEEKDAY.Wednesday,
});
// Generated dates:
// Wed, December 28, 2022 at 12:00:00 AM -> The first date of the range
// Thu, December 29, 2022 at 12:00:00 AM
// Fri, December 30, 2022 at 12:00:00 AM
// ...
// Tue, January 31, 2023 at 12:00:00 AM -> The last date of the range
Creates a single week range.
By default, the method starts the range on Monday before or on the reference date and ends it on Sunday after or on the reference date.
If the start of the week is changed from Monday to a different day, the end of the week will also be shifted accordingly.
The reference date is set to the current day if not specified otherwise.
Each date is set to the start of the day (midnight).
public getWeek(options?: OptionsWeek): DateRange
Parameter | Type | Description |
---|---|---|
options | OptionsWeek | An object to configure the range. |
Options properties
Property | Type | Description |
---|---|---|
refDate | DateTime | Date | The reference date to calculate the range. |
refWeekday | WEEKDAY | The reference weekday to start the range from. |
startOffset | number | The number of days to add or remove from the beginning of the range. |
endOffset | number | The number of days to add or remove from the end of the range. |
// get current week starting on Monday
const currentWeek = new DateRange().getWeek();
// get week based on a refDate and starting on Sunday
const week2 = new DateRange().getWeek({
refDate: new Date('2023-01-10'),
refWeekday: WEEKDAY.Sunday,
});
// Generated dates:π
// Sun, January 8, 2023 at 12:00:00 AM
// Mon, January 9, 2023 at 12:00:00 AM
// Tue, January 10, 2023 at 12:00:00 AM
// Wed, January 11, 2023 at 12:00:00 AM
// Thu, January 12, 2023 at 12:00:00 AM
// Fri, January 13, 2023 at 12:00:00 AM
// Sat, January 14, 2023 at 12:00:00 AM
Generates the next range based on given one.
The method takes the refDate
and rangeType
from the DateRange
argument and assigns a new refDate
which can produce a new range that is one interval after the current one.
The method shifts the refDate to the next one as follows:
- for a range generated with
getDays
, therefDate
is incremented by thedaysCount
property. - for a range generated with
getWeek
, therefDate
is incremented by 7 days. - for a range generated with
getMonthExact
andgetMonthExtended
, therefDate
is set to the first day of the next month.
The options used to adjust the given range are copied and applied to the new range.
In all cases, the refDate
is set to the start of the day (midnight).
To check whether the range is generated with a getNext
method, access the isNext
property on its instance.
public getNext(dateRange: DateRange): DateRange
Parameter | Type | Description |
---|---|---|
dateRange | DateRange | A DateRange object with initialized range. |
Generates the previous range based on given one.
The method takes the refDate
and rangeType
from the DateRange
argument and assigns a new refDate
which can produce a new range that is one interval after the current one.
The method shifts the refDate
to the previous one as follows:
- for a range generated with
getDays
, therefDate
is decremented by thedaysCount
property. - for a range generated with
getWeek
, therefDate
is decremented by 7 days. - for a range generated with
getMonthExact
andgetMonthExtended
, therefDate
is set to the first day of the previous month.
The options used to adjust the given range are copied and applied to the new range.
In all cases, the refDate
is set to the start of the day (midnight).
To check whether the range is generated with a getPrevious
method, access the isPrevious
property on its instance.
public getPrevious(dateRange: DateRange): DateRange
Parameter | Type | Description |
---|---|---|
dateRange | DateRange | A DateRange object with initialized range. |
Checks if a given value is a valid offset.
public isValidOffset(offset: unknown): boolean
Parameter | Type | Description |
---|---|---|
offset | unknown | The value to check. |
boolean
- True if the value is an integer, false otherwise.
Checks if a given value is a valid reference date.
public isValidRefDate(refDate: unknown): boolean
Parameter | Type | Description |
---|---|---|
refDate | unknown | The value to check. |
boolean
- True if the value is a valid reference date, false otherwise.
Checks if a given value is a valid weekday (integer from 1 to 7).
public isValidRefWeekday(weekday: unknown): boolean
Parameter | Type | Description |
---|---|---|
weekday | unknown | The value to check. |
boolean
- True if the value is a valid weekday, false otherwise.
Returns an array of dates generated for the instance as JS Date objects.
public toDates(): Date[]
The methods doesn't accept parameters.
Date[]
- An array of JavaScript Dates.
Returns an array of dates generated for the instance as Luxon DateTime objects.
public toDateTimes(): DateTime[]
The methods doesn't accept parameters.
DateTime[]
- An array of Luxon DateTimes.
/**
* Options for the DateRange `getMonthExact()` method.
*/
export type RangeOptionsMonthExact = Omit<RangeOptions, 'refWeekday'>;
/**
* Options for the DateRange `getDays()` method.
*/
export type RangeOptionsDays = Omit<RangeOptions, 'refWeekday'> & {
daysCount?: number;
};
interface DaysCount {
/**
* The number of days to be included in the range generated with `getDays` method.
*/
daysCount?: number;
}
export interface Offset {
/**
* The number of days to add or remove from the beginning of the range.
*
* @remarks
* If the specified offset is positive, dates are added. If negative, dates are removed.
*
* @defaultValue `0`
*
* @example
* ```
* // set the reference date
* const refDate = new Date("2020-01-17");
*
* // with no offset π
* const month1 = new DateRange().getMonthExact({ refDate });
* // first date in range
* month1.dateTimes[0]; // Jan 1, 2020
* // last date in range
* month1.dateTimes[month1.dateTimes.length - 1]; // Jan 31, 2020
*
* // with positive startOffset π
* const month2 = new DateRange().getMonthExact({ refDate, startOffset: 5 });
* // first date in range
* month2.dateTimes[0]; // Dec 27, 2020
* // last date in range (no changes)
* month2.dateTimes[month2.dateTimes.length - 1]; // Jan 31, 2020
*
* // with negative startOffset π
* const month3 = new DateRange().getMonthExact({ refDate, startOffset: -5 });
* // first date in range
* month3.dateTimes[0]; // Jan 6, 2020
* // last date in range (no changes)
* month3.dateTimes[month3.dateTimes.length - 1]; // Jan 31, 2020
* ```
*/
startOffset?: number;
/**
* The number of days to add or remove from the end of the range.
*
* @remarks
* If the specified offset is positive, dates are added. If negative, dates are removed.
*
* @defaultValue `0`
*
* @example
* ```
* // set the reference date
* const refDate = new Date("2020-01-17");
*
* // with no offset π
* const month1 = new DateRange().getMonthExact({ refDate });
* // first date in range
* month1.dateTimes[0]; // Jan 1, 2020
* // last date in range
* month1.dateTimes[month1.dateTimes.length - 1]; // Jan 31, 2020
*
* // with positive endOffset π
* const month2 = new DateRange().getMonthExact({ refDate, endOffset: 5 });
* // first date in range (no changes)
* month2.dateTimes[0]; // Jan 1, 2020
* // last date in range
* month2.dateTimes[month2.dateTimes.length - 1]; // Feb 5, 2020
*
* // with negative endOffset π
* const month3 = new DateRange().getMonthExact({ refDate, endOffset: -5 });
* // first date in range (no changes)
* month3.dateTimes[0]; // Jan 1, 2020
* // last date in range
* month3.dateTimes[month3.dateTimes.length - 1]; // Jan 26, 2020
* ```
*/
endOffset?: number;
}
interface RefDate {
/**
* The reference date to calculate the range.
*
* @remarks
* Must be a Date object or luxon DateTime object.
* Defaults to current time.
*
* @example
* ```
* // with DateTime
* new DateRange().getWeek({ refDate: DateTime.fromISO('2023-05-15') });
*
* // with Date
* new DateRange().getWeek({ refDate: new Date("2023-05-15") });
* ```
*/
refDate?: DateTime | Date;
}
interface RefWeekday {
/**
* The reference weekday to start the range from.
*
* @remarks
* Must be an integer from 1 (Monday) to 7 (Sunday).
* Defaults to Monday.
*
*@example
* ```
* // with WEEKDAY enum. The range will start from Sunday
* new DateRange().getWeek({refWeekday: WEEKDAY.Sunday });
* // the equivalent with a number
* new DateRange().getWeek({ refWeekday: 7 });
* ```
*/
refWeekday?: WEEKDAY;
}
interface OptionsDays extends RefDate, DaysCount, Offset {}
interface OptionsWeek extends RefDate, RefWeekday, Offset {}
interface OptionsMonthExact extends RefDate, Offset {}
interface OptionsMonthExtended extends RefDate, RefWeekday, Offset {}
/**
* An enum that represents the type of date range that is generated and stored by DateRange instance.
*
* It corresponds to the range generator method used to create the range:
* - `WEEK` for `getWeek`
* - `MONTH-EXACT` for `getMonthExact`
* - `MONTH-EXTENDED` for `getMonthExtended`
* - `DAYS` for `getDays`
*/
export enum RANGE_TYPE {
Week = 'WEEK',
MonthExact = 'MONTH-EXACT',
MonthExtended = 'MONTH-EXTENDED',
Days = 'DAYS',
}
/**
* An enum that represents the weekdays as numbers from 1 to 7.
*/
export enum WEEKDAY {
Monday = 1,
Tuesday = 2,
Wednesday = 3,
Thursday = 4,
Friday = 5,
Saturday = 6,
Sunday = 7,
}
easy-date-range is licensed under the MIT license.