Turns a rule string like "4th thursday in November" or
"substitutes 12-25 if saturday then previous friday" into tokens.
A port of the reference implementation's Parser.js: an ordered list of
anchored regular expressions is tried at the head of the remaining string,
the first match wins and is consumed, spaces are skipped, and a pass that
consumes nothing makes the rule unparseable. Two token reorderings follow,
see reorder/1. The grammar is documented in the "Rules" guide.
Tokens are maps of three kinds:
%{fn: ...}produce candidate dates for a year (:gregorian,:julian,:easter,:equinox,:hebrew,:islamic,:jalaali,:chinese,:korean,:vietnamese,:bengali_revised)%{rule: ...}move, filter or annotate those dates%{modifier: ...}change how the following rules behave (:substitutes,:and,:if,:then,:if_equal)iex> Dayoff.Parser.parse!("12-25 and if sunday then next monday") [ %{fn: :gregorian, year: nil, month: 12, day: 25}, %{modifier: :and}, %{rule: :date_if_then, if: [:sunday], direction: :next, then: :monday, rules: []} ]
Summary
Functions
Parses a rule string, {:error, :unparseable} when part of it matches no
production.
Like parse/1 but raises ArgumentError.
The two reorderings the reference parser applies after tokenizing.
Types
Functions
Parses a rule string, {:error, :unparseable} when part of it matches no
production.
Like parse/1 but raises ArgumentError.
The two reorderings the reference parser applies after tokenizing.
Buffered date_dir tokens come out reversed after the next other token,
so friday after 4th thursday in November evaluates November 1st, then
the 4th Thursday, then the Friday after it. Modifiers written before the
first fn token are rotated behind it, so substitutes 01-01 if ...
applies the modifier after the date exists.
iex> Dayoff.Parser.parse!("friday after 4th thursday in November") |> Enum.map(&Map.take(&1, [:fn, :rule, :count, :weekday]))
[%{fn: :gregorian}, %{rule: :date_dir, count: 4, weekday: :thursday}, %{rule: :date_dir, count: 1, weekday: :friday}]
iex> Dayoff.Parser.parse!("substitutes 01-01 if Sunday then next Monday") |> Enum.map(&Map.take(&1, [:fn, :rule, :modifier]))
[%{fn: :gregorian}, %{modifier: :substitutes}, %{rule: :date_if_then}]