An API to get available time slots. It's possible to provide a calendar containing existing events.
Disclaimer
This module is currently still in pre-version. BREAKING CHANGES may occurs in MINOR versions. Use it with care.
- Define slots duration
- Require free time before and/or after slots
- Define bookable shifts for day of the week
- Work with or without calendar data
- Handle iCal format for calendar data
- Take time zones in account when parsing calendar and for the configuration
- Includes TypeScript definitions
- High test coverage
npm install --save time-slots-finder
yarn add time-slots-finder
import * as TimeSlotsFinder from "time-slots-finder"
const slots = TimeSlotsFinder.getAvailableTimeSlotsInCalendar({
calendarData: "SOME ICAL DATA",
calendarFormat: TimeSlotsFinder.TimeSlotsFinderCalendarFormat.iCal,
configuration: {
timeSlotDuration: 15,
minAvailableTimeBeforeSlot: 5,
minTimeBeforeFirstSlot: 48 * 60, // 48 hours in minutes
availablePeriods: [{
isoWeekDay: 5,
shifts: [{ startTime: "10:00", endTime: "20:00" }]
}, {
isoWeekDay: 6,
shifts: [
{ startTime: "10:00", endTime: "20:00" },
{ startTime: "10:00", endTime: "13:00" },
]
}],
timeZone: "Europe/Paris",
},
from: new Date("2020-09-21T00:00:00.000+02:00"),
to: new Date("2020-11-12T23:59:59.999+02:00"),
})
/**
* This will returns all free time slots between September's 21th and
* November's 12th, only for all Friday from 10 AM to 8 PM (Paris time) and
* Satursday from 10 AM to 1 PM. All slots will be 15 minutes long with 5
* minutes free before each. If we were the 21th of September the first slot
* would have been on the the 23th (since we require 48 hours before the first
* availabilities.
*/
A TimeSlot is represented as follows:
{
/* The start date of the period */
startAt: Date
/* The end date of the period */
endAt: Date
/* The duration of the slot in minutes */
duration: number
}
/* Required. The length of the time slots in minutes. */
timeSlotDuration: number
/**
* A number indicating the step for the start minute of a slot.
* E.g. if the multiple is 15, slots can only begin at XX:00, XX:15, XX:30 or XX:45.
* Default value is 5.
*/
slotStartMinuteStep: number
/* Required. Bookable periods for each day of the week. */
availablePeriods: [{
isoWeekDay: number, // 1 (Monday) - 7 (Sunday)
shifts: [{
startTime: string, // Format "HH:mm"
endTime: string, // Format "HH:mm"
}]
}]
/**
* Periods where no booking is allowed.
*
* Objet containing at least month and day values.
* If years are ommited, event repeat every years.
* If hour are ommited, all day is included: hour 00:00 is used for startAt and 23:59 is used for
* endAt.
* Month are 0 indexed, i.e. January is 0 and December is 11.
* An unavailable period MUST have year defined for BOTH OR NONE of startAt and endAt.
*/
unavailablePeriods: [{
startAt: { year?: number, month: number, day: number, hour?: number, minute?: number },
endAt: { year?: number, month: number, day: number, hour?: number, minute?: number },
}]
/* The minimum number of free minutes required before a slot. */
minAvailableTimeBeforeSlot: number
/* The minimum number of free minutes required after a slot. */
minAvailableTimeAfterSlot: number
/**
* The minimum number of minutes between the time of the search and the first slot
* returned.
*/
minTimeBeforeFirstSlot: number
/* The maximum days from now before slots cannot be returned anymore. */
maxDaysBeforeLastSlot: number
/* Required. The time zone used through all the configuration. */
timeZone: string
If you want to check that a configuration is valid without running a search,
you can use the isConfigurationValid
function as follows:
import * as TimeSlotsFinder from "time-slots-finder"
const config = {
timeSlotDuration: 15,
availablePeriods: [{
isoWeekDay: 5,
shifts: [{ startTime: "20:00", endTime: "10:00" }]
}, {
isoWeekDay: 6,
shifts: [
{ startTime: "10:00", endTime: "20:00" },
{ startTime: "10:00", endTime: "13:00" },
]
}],
timeZone: "Europe/Paris",
}
try {
TimeSlotsFinder.isConfigurationValid(config) // returns true is valid
} catch (error) {
/**
* Throws error if configuration is invalid.
* The error indicate why and where the configuration is invalid.
*
* Here the error is:
* "TimeSlotsFinderError: Daily shift 20:00 - 10:00 for work period nº1 is invalid"
*/
}
- We consider handling more calendar formats in the future.
- The API may change until the first version (v1.0.0) is released