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. With clamp: false the fields are returned as counted, and may not be a date of the calendar.

Summary

Types

A calendar module.

A unit of the shift.

Functions

Returns the whole number of units from one date of the calendar to another, as shift/7 adds them.

Returns the date a number of units on from a date of the calendar.

Types

calendar()

@type calendar() :: module()

A calendar module.

unit()

@type unit() :: :years | :quarters | :months | :weeks | :days

A unit of the shift.

Functions

diff(calendar, from, to, unit)

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

  • calendar is a calendar module.

  • from and to are dates of the calendar as {year, month, day}.

  • unit is one of :years, :quarters, :months, :weeks or :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

shift(calendar, year, month, day, atom, years, options)

Returns the date a number of units on from a date of the calendar.

Arguments

  • calendar is a calendar module.

  • year, month and day are the fields of a date of the calendar.

  • unit is one of :years, :quarters, :months, :weeks or :days.

  • count is the number of units, which may be negative.

  • options is a keyword list of options.

Options

  • :clamp is whether a day the resulting month lacks becomes its last day. The default is true.

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}