almanac implements a grammar of schedules, providing the fundamental rules and concepts that allow you to build up a schedule of “events”, such as holidays or weekends. After creating a schedule from the fundamental rules, it can be used to:

  • Generate dates that fall in the schedule.

  • Determine if a date is in the schedule or not.

  • Shift a sequence of dates, stepping over or avoiding dates that fall in the schedule.

library(magrittr)
library(almanac)

Installation

You can NOT install the released version of almanac from CRAN with:

And the development version from GitHub with:

Events

An event is a set of rules that define a reoccuring date, such as New Years Day, or the third Monday in November.

Events are created from a family of related functions that all start with one of:

  • on_*()

  • before_*()

  • after_*()

  • between_*()

For example, on_mday(25) defines the reoccuring event of the 25th day of the month.

To determine if a date falls on an event, use event_in().

event_in("2019-01-25", on_25th)
#> [1] TRUE

event_in("2019-01-23", on_25th)
#> [1] FALSE

event_in("2019-02-25", on_25th)
#> [1] TRUE

Events can be combined by taking an intersection, a union, or a difference. Here, we take an intersection, which should be read as “the 25th of the month and the month of November” to define the event of November 25th.

It’s often easier to use the shortcut operators &, |, and -.

event_in("2019-11-24", on_nov_25th)
#> [1] FALSE

event_in("2019-11-25", on_nov_25th)
#> [1] TRUE

Schedules

A schedule is a collection of events. You can create them by starting with an empty schedule(), and then adding events with sch_add().

Check if a date is in a schedule with sch_in().

sch_in("2019-01-01", sch)
#> [1] FALSE

sch_in("2019-12-25", sch)
#> [1] TRUE

Generate dates in the schedule with sch_seq().

If you have an existing set of dates, you can adjust them relative to the schedule with sch_adjust(). If a date happens to fall on an event in the schedule, then an adjustment is applied repeatedly until the next non-event date is found.

You can shift a set of dates relative to the schedule with sch_jump() and sch_step().

Jumping applies a period shift all at once. You start at x and end at x + jump. If, after the jump, the date you landed on is an event, an adjustment is made to find the next non-event date.

In the above example, jumping forward 2 days might not have the intended result if you wanted to look forward “2 business days”. In those cases, use sch_step(). This steps 1 day at a time, and after each step checks if the date you are on is an event. If it is, it applies the adjustment, then continues to the next step.

Acknowledgements

almanac is a combination of ideas from the date library of QuantLib with the great package from James Laird-Smith, gs. Both gs and almanac are based on a paper written by Martin Fowler, which outlines the grammar for reoccuring events and schedules.

The hope is that gs and almanac will merge, as they currently overlap a large amount.