Calendrical. Shift
(Calendrical v2.2.0)
Copy Markdown
Date arithmetic for a calendar whose months are counted by their
position in the year: the implementation of Calendrical.shift/6
and Calendrical.diff/3 that use Calendrical.Calendar supplies,
computed from the calendar's kernel.
The contract every calendar's shift/6 honours, whatever its maker:
Days and weeks are counted on the day line, through
Calendrical.date_to_iso_days/3.Months are counted by position: the next month is the next position in the year, or the first of the year after. A quarter is three months.
Years keep the month as the calendar's culture names it, its traditional number (
Calendrical.Month.traditional_month/3), so Nisan stays Nisan whatever its position, and a leap month the resulting year lacks becomes the month it repeats.A count that reaches or crosses a year 0 the calendar does not have (
info().year_zero?) goes one year further the way it was going.With
clamp: true, the default, a day the resulting month lacks becomes the month's last day. Withclamp: falsethe fields are returned as counted, and may not be a date of the calendar.
Summary
Types
@type calendar() :: module()
A calendar module.
@type unit() :: :years | :quarters | :months | :weeks | :days
A unit of the shift.
Functions
@spec diff( calendar(), {Calendar.year(), Calendar.month(), Calendar.day()}, {Calendar.year(), Calendar.month(), Calendar.day()}, unit() ) :: integer()
Returns the whole number of units from one date of the calendar to
another, as shift/7 adds them.
The count is the largest number of units that shift/7 can add to the
earlier date without passing the later one, and is negative when to
is before from.
Arguments
calendaris a calendar module.fromandtoare dates of the calendar as{year, month, day}.unitis one of:years,:quarters,:months,:weeksor:days.
Returns
- An integer.
Examples
iex> Calendrical.Shift.diff(Calendrical.Gregorian, {2026, 1, 31}, {2026, 2, 28}, :months)
1
iex> Calendrical.Shift.diff(Calendrical.Hebrew, {5784, 6, 30}, {5785, 6, 29}, :months)
13
@spec shift( calendar(), Calendar.year(), Calendar.month(), Calendar.day(), unit(), integer(), keyword() ) :: {Calendar.year(), Calendar.month(), Calendar.day()}
Returns the date a number of units on from a date of the calendar.
Arguments
calendaris a calendar module.year,monthanddayare the fields of a date of the calendar.unitis one of:years,:quarters,:months,:weeksor:days.countis the number of units, which may be negative.optionsis a keyword list of options.
Options
:clampis whether a day the resulting month lacks becomes its last day. The default istrue.
Returns
{year, month, day}of the calendar.
Examples
iex> Calendrical.Shift.shift(Calendrical.Gregorian, 2026, 1, 31, :months, 1, [])
{2026, 2, 28}
iex> Calendrical.Shift.shift(Calendrical.Gregorian, 2026, 1, 31, :months, 1, clamp: false)
{2026, 2, 31}
# Adar I of the leap year 5784 becomes Adar in 5785, which has 29 days
iex> Calendrical.Shift.shift(Calendrical.Hebrew, 5784, 6, 30, :years, 1, [])
{5785, 6, 29}
# 15 Nisan, the 8th month of the leap year 5784 and the 7th of 5785
iex> Calendrical.Shift.shift(Calendrical.Hebrew, 5784, 8, 15, :years, 1, [])
{5785, 7, 15}
# The Julian calendar has no year 0
iex> Calendrical.Shift.shift(Calendrical.Julian, -1, 6, 15, :years, 1, [])
{1, 6, 15}