Calendrical.Composite (Calendrical v0.3.0)

Copy Markdown

A composite calendar uses one base calendar before a specified transition date and a different calendar after, optionally chaining multiple transitions to model a sequence of historical calendar reforms.

The canonical example is the European transition from the Julian to the Gregorian calendar between the 16th and 20th centuries, where the calendar in use literally changed on a known date and a window of "missing" days appeared in the historical record.

Configuration

A composite calendar is built by useing this module with a :calendars option listing the first day on which a new calendar takes effect. Each entry must be a Date literal expressed in the calendar that takes effect on that day.

defmodule MyApp.England do
  use Calendrical.Composite,
    calendars: [
      ~D[1752-09-14 Calendrical.Gregorian]
    ],
    base_calendar: Calendrical.Julian
end

The :base_calendar option indicates the calendar in use before any of the configured transitions. It defaults to Calendrical.Julian.

Julian to Gregorian transition

One of the principal uses of this calendar is to define a calendar that reflects the historical Julian-to-Gregorian transition for individual countries.

Applicable primarily to western European countries and their colonies, the transition occurred between the 16th and 20th centuries. A strong reference is the Perpetual Calendar site maintained by Toke Nørby. Wikipedia's Adoption of the Gregorian calendar page is also useful.

Multiple compositions

A more complex example chains more than one calendar. For example, Egypt used the Coptic calendar from 238 BCE until Rome introduced the Julian calendar in approximately 30 BCE. The Gregorian calendar was then introduced in 1875. We can approximate this with:

defmodule MyApp.Egypt do
  use Calendrical.Composite,
    calendars: [
      ~D[-0045-01-01 Calendrical.Julian],
      ~D[1875-09-01 Calendrical.Gregorian]
    ],
    base_calendar: Calendrical.Coptic
end

Missing days

When a transition skips dates (for example the British transition on 14 September 1752 dropped the eleven days 3 September 1752 through 13 September 1752), the composite calendar treats those dates as invalid:

iex> Calendrical.England.valid_date?(1752, 9, 5)
false

iex> Date.shift(~D[1752-09-02 Calendrical.England], day: 1)
~D[1752-09-14 Calendrical.England]

Summary

Functions

Creates a new composite calendar at runtime.

Functions

new(calendar_module, options)

@spec new(module(), Keyword.t()) ::
  {:ok, Calendrical.calendar()} | {:module_already_exists, module()}

Creates a new composite calendar at runtime.

Arguments

  • calendar_module is the module name to be created. This will be the name of the new composite calendar if it is successfully created.

  • options is a keyword list of options. See Calendrical.Composite for the supported options.

Returns

  • {:ok, module} or

  • {:module_already_exists, calendar_module}

Examples

iex> Calendrical.Composite.new(MyApp.Denmark,
...>   calendars: [~D[1700-03-01 Calendrical.Gregorian]])
{:ok, MyApp.Denmark}