A JavaScript library for parsing colloquial date/time and date/time range strings
This library began as an experiment in the use of parser combinators as a technique for coping with the variety and ambiguity of natural date/time and date/time range strings found in the wild. The idea was to define a set of elemental parser functions for the various elements of date/time phrases -- year, month, day, hour, minute, etc. -- and then use a set of combinator functions to combine these into more complex parsers that encode the various ways the elements can be combined to form a date/time or date/time range phrase.
Importantly, rather than returning a single parse result, each parser function returns an array representing the set of successful parses, all of which propagate up through the layers of higher-level parsers, ulimately yielding a set of possible parses for the input phrase rather than a single parse.
The overall parser works as follows:
-
The input is passed to the top-level (i.e. phrase) parser function, which returns an array containing the entire set of successful parses.
-
If the array contains more than 1 entry, a score is assigned to each parse based on some measure(s). The current implementation uses a single measure, which is the number of input tokens consumed i.e. a parse that consumed the entire input string scores twice as high as one that consumed only half of it. (While this simple heuristic seems to work rather well in practice, it could certainly be augmented to incorporate additional measures, such as preferring parses that conform to the standard way of formatting dates/times in the current culture.)
-
Return the result of the highest scoring parse. In the case of a tie, either throw an "ambiguous input" exception, or choose one of the tied results arbitrarily, depending on the option specified by the caller.
The following are a few examples of the types of phrases that the parser can recognize.
- Aug 24th 2017
- August 24 2017 at 8 pm
- Tomorrow 8pm
- August 24 2017 8:00 - 10:00 pm
- May 27 5pm - May 30 12pm
- Aug 28th-29th @ 5pm
- May 27 - December 31 from 12:00 PM - 5:00 PM
For more examples, open the test page in a browser.