A JS library for checking dates of recurring events and holidays
The purpose of this library is allowing to filter data that is associated with specific dates, partial dates (e.g. month-year), holidays, days of the week, etc. by checking against particular dates. It was developed for filtering lists of MOTDs, special announcements and config files that override settings depending on the time of the year.
Whenzel can be used in node.js:
const Whenzel = require('whenzel');
or in a browser via the global Whenzel
.
The test
method allows you to check if a date matches a selector pattern. You can pass any
Date
as the second parameter or the current date will be used by default.
const date = new Date(2019, 11, 25);
const christmas2019 = Whenzel.test('2019-12-25', date);
In applications you should consider always explicitly passing a date, because that way you can test the effect of different dates without changing the computer's clock.
const todayIsChristmas2019 = Whenzel.test('2019-12-25');
const todayIsChristmas = Whenzel.test('????-12-25');
const todayIsTheFirst = Whenzel.test('????-??-01');
You can replace any (or all) of the parts of the date by question marks to match any year, month or day. You
must use four question marks for the year (????
) or two question marks for the month or day (??
). It's not
possible to use a partial pattern such as 20??
or 1?
.
const inSummer2018 = Whenzel.test('2019-06-21 / 2018-09-23');
const inSummer = Whenzel.test('????-06-21 / ????-09-23');
const inJanuary = Whenzel.test('????-01-01 / ????-01-31');
const first5Days = Whenzel.test('????-??-01 / ????-??-05');
Use /
to separate two dates (complete or partial) to match either of them or any day in between.
It's also possible to match any date below or over a date:
const beforeChristmas2019 = Whenzel.test('????-??-?? / 2019-12-25');
const afterChristmas2019 = Whenzel.test('2019-12-26 / ????-??-??');
const 2019BeforeMay = Whenzel.test('2019-??-?? / 2019-05-01');
Range matching supports rollover:
const itsWinter = Whenzel.test('????-12-21 / ????-03-21');
const not5to10 = Whenzel.test('????-??-10 / ????-??-05');
The library allows using symbolic names for certain holidays and moments of the year:
const todayIsChristmas = Whenzel.test('@christmas');
A delta (in days) can also be specified:
const aroundChristmas = Whenzel.test('@christmas-3 / @christmas+3');
NOTE: Deltas are calculated based on the year being checked, which might cause a difference depending on whether it's a leap year or not. Thus, it's possible to get a range that's off by one when using deltas in ranges that begin on one year and end on the next. Don't use this library to operate nuclear facilities, petroleum extraction platforms, yada yada yada.
The list of available symbols is:
-
@christmasEve
-
@christmas
-
@boxingDay
-
@newYearsEve
-
@newYear
-
@halloween
-
@allSaintsDay
-
@aprilFools
-
@earthDay
-
@valentinesDay
-
@stPatrick
-
@laborDay
-
@piDay (3/14)
-
@idm (International Day of Mathematics)
and even some events that change date every year (these are calculated according to the date being checked):
- @easter
- @chineseNewYear
- @roshHashanah
- @hanukkahStart
- @hanukkahEnd
NOTE: Although these symbolic names can be used in ranges, they're resolved against the date
being checked: so ranges that wrap around from one year to the next will be considered empty. When
checking hannukkah use @hannukahStart / @hannukahEnd
instead of a delta for this very reason.
Filters allow seeing if the date matches special conditions that go beyond what patterns and ranges can express. They can be used on their own or combined with other patterns. Place filters separated by spaces after any pattern.
const itsMonday = Whenzel.test('#monday');
const firstSunday = Whenzel.test('#sunday #week1');
const mondaysInJanuary = Whenzel.test('????-01-01 / ????-01-31 #monday');
Available filters are:
-
#monday
-
#tuesday
-
#wednesday
-
#thursday
-
#friday
-
#saturday
-
#sunday
-
#weekday
-
#weekend
-
#week1
-
#week2
-
#week3
-
#week4
-
#week5
-
#week6
-
#firstDayOfMonth
-
#lastDayOfMonth
-
#leapDay (matches the 29th of february)
-
#pythagoras (matches if year^2 = month^2 + day^2)
-
#always
-
#never
If Whenzel finds an error in the expression being tested it'll throw an exception with a description of the problem found.
Copyright 2019 IMAGINARY gGmbH
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.