visiting-hours
v2.0.0
Published
An advanced, feature rich, optimised and tiny visiting-hours library.
Downloads
5
Maintainers
Readme
🕐 Visiting hours
A simple library that allows you to provide visiting hours and extract information from it based on a provided Date.
This library was built to run continuously and for that reason optimized for lookup speed.
Features
Some of the features and characteristics of this library.
- 0 Dependencies 🦄
- Live mode, returns same reference when in cache (useful with mobx)
- 3.9 kB (minified + gzipped)
- Timezone support (specify zone in config or luxon instance or
DateInputInterface
in method calls.) - Multiple ranges on days (allows for lunch breaks! 🥪)
- Check if provided Date falls within visiting hours
- Allows special dates to be provided (holidays and such)
- Works past-midnight
- Works with leap years (even for special dates)
- Check if open at all on provided Date's day, and if so at what time
- Extensive test coverage
This library is optimized to perform well when called frequently for many venues.
Usage
I prefer code over lengthy explanations so, take a gander:
import { VisitingHours, Utils, Timezone } from 'visiting-hours';
import { DateTime } from 'luxon';
const hours = new VisitingHours({
// Optional. Requires IANA tz identifiers.
// zone: 'America/New_York',
live: false, // Set to true to optimize for frequent lookups.
regular: {
sunday: { isOpen: false },
monday: {
hours: [
{ open: '08:00', close: '12:00' },
// Had a really nice lunch break
{ open: '13:30', close: '20:00' },
// Past midnight
{ open: '23:30', close: '03:30' },
],
isOpen: true
},
friday: {
hours: [
{ open: '08:00', close: '18:00' }
],
isOpen: true
},
},
special: [
// This venue is down with Christmas.
{ date: '25/12', isOpen: false }
]
});
// Monday, July 13th of 2020 at 11:15, result: true
hours.isOpen(new Date(2020, 6, 13, 11, 15)).open;
// Monday, July 13th of 2020 at 12:35, result: false
hours.isOpen(new Date(2020, 6, 13, 12, 35)).open;
// Tuesday, July 14th of 2020 at 02:15, result: true
hours.isOpen(new Date(2020, 6, 14, 2, 15)).open;
// Friday, July 17th of 2020 at 14:15, result: true
hours.isOpen(new Date(2020, 6, 17, 14, 15)).open;
// Friday, December 25th of 2020 at 14:15, result: false
hours.isOpen(new Date(2020, 11, 25, 14, 15)).open;
// You can use luxon objects, too.
hours.isOpen(DateTime.local()).open;
// Or use vanilla JS for timezone support
// (requires IANA tz identifiers. Modern browsers will work.)
hours.isOpen(Utils.fromDate(new Date(2020, 6, 16, 15, 40), 'Europe/Amsterdam')).open;
// Small utility function to make range of hours
Utils.minuteInterval('08:01', '09:14', 15); // ['08:15', '08:30', '08:45', '09:00']
// Get a Date representing a value in the future
Timezone.fromTimeString('02:00', 'Europe/Amsterdam', new Date());
Interfaces
Sometimes it's nice to know what's possible by taking a quick look at the README. This is one of those times!
VisitingHoursConfigInterface
| key | type | required | description |
|---|---|---|---|
| live | boolean
| false
| Will expect frequent lookups and optimize accordingly when set to true |
| zone | string
| false
| IANA timezone identifier, will be applied to all Date arguments used on this instance.Examples: Europe/Amsterdam
or America/New_York
|
| regular | RegularHoursInterface
| false
| Regular visiting hours for week days. |
| special | HoursDayInterface[]
| false
| Override visiting hours, for example holidays.Example: { date: '25/12', isOpen: false }
|
RegularHoursInterface
An interface where the key is the name of the week, and the value is an HoursDayInterface. Example:
Example:
{
sunday: { isOpen: false },
monday: {
hours: [
{ close: '01:00', open: '11:15' }
],
isOpen: true
}
}
DateInputInterface
An object that contains all the info needed and allows you to use your own timezone changes or other magic.
| key | type | required | description |
|---|---|---|---|
| zoneName | number
| false
| The name of the timezone this instance is in. Required for live
and zone
. |
| ts | number
| true
| The timestamp of the date object. |
| offset | number
| true
| The timezone offset of the date object. |
| month | number
| true
| The month of the date object. |
| day | number
| true
| The day of the date object. |
| weekday | number
| true
| The weekday of the date object. |
| hour | number
| true
| The hour(s) of the date object. |
| minute | number
| true
| The minute(s) of the date object. |
| isInLeapYear | boolean
| true
| If this object's date falls in a leap year. |
HoursDayInterface
Holds opening hours for a week day or specific date (when it's an override).
| key | type | required | description |
|---|---|---|---|
| date | string
| false
| Used for special dates. Format: dd/mm
|
| isOpen | boolean
| true
| Used to specify if open on specified day/date. Note: will ignore provided hours when false. |
| hours | HoursInterface[]
| false
| The hours for this day/date. |
HourMatchInterface
This is the shape you'll get back when calling .isOpen()
.
| key | type | description |
|---|---|---|
| open | boolean
| If the provided date fall within visiting hours |
| match | HourMatchSetInterface
or null
| Objects of the opening and closing hours matched or null. |
| soonest | VisitingHour
or null
| If no match, the soonest match for the provided day or null when closed all day. |
VisitingHour
An instance with a few getters that represent an opening hour.
| key | type | description |
|---|---|---|
| hours | number
| The hours of the matched time. |
| minutes | number
| The minutes of the matched time. |
| military | string
| The match in military notation. |
| date | Date
| Date
instance of the matched time. |
| formatted | string
| Returns .toLocaleTimeString()
on date
|
HourMatchSetInterface
A set of open/close hours.
| key | type | description |
|---|---|---|
| open | VisitingHour
| Open value of the matched visiting hours. |
| close | VisitingHour
| Close value of the matched visiting hours. |
Compatibility
Works in all modern browsers. Most features should work in IE (caches an timezones require Polyfills.),
React Native: Android
For android you have two options:
- jsc-android-buildscripts (recommended)
- Polyfills (include all required polyfills, there's a chart)
When using a polyfill you can prevent from adding to your bundle size on iOS and Web by using a polyfills.android.js
file to only include them on android. Make sure to import the polyfills file in your App.js file.
License
MIT