Calendrical behaviour (Calendrical v2.2.0)
Copy MarkdownCalendar functions for calendars compatible with
Elixir's Calendar behaviour.
Calendrical supports the creation of calendars
that are variations on the proleptic Calendrical.Gregorian
calendar. It also adds additional functions, defined
by the Calendrical behaviour, to support these
derived calendars.
The common purpose of these derived calendars is to support the creation and use of financial year calendars that are commonly used in business.
There are two general types of calendars supported:
monthcalendars that mirror the monthly structure of the prolepticCalendrical.Gregoriancalendar but which are deemed to start the year in a month other than January.weekcalendars that are defined to have a 52 week structure (53 weeks in a long year). These calendars can be configured to start or end on the first, last or nearest day to the beginning or end of aCalendrical.Gregorianmonth. The main intent behind this structure is to have each year start and end on the same day of the week with a consistent 13-week quarterly structure than enables a more straight forware comparison with same-period-last-year financial performance.
The Calendrical behaviour
A Calendrical calendar implements Elixir's Calendar behaviour and
the eight callbacks of this module beside it, which are its kernel:
info/0is the static facts about the calendar, asCalendrical.Info.t/0: the CLDR calendars that name its months and its eras, its epoch, whether it has a year 0, the fewest and the most months its years have, the rule its own weeks follow, the cycles its years run in, and, for a composite, its members.date_to_iso_days/3anddate_from_iso_days/1are the spine every conversion runs through.leap_month/1is the position of a year's leap month, ornil.written_date/3is the figures a date is written with, anddate_from_written_date/3the date those figures name: a fiscal date is written as the Gregorian date it is, a Hebrew date with its month's place in the year as ICU writes it.shift/6anddiff/3are the calendar's arithmetic, under one clamping contract.
Every other answer, from the day of the week to the days of a quarter,
is derived from the kernel and from the six primitive Calendar
callbacks by Calendrical.Month, Calendrical.Week,
Calendrical.Period and Calendrical.Era, and every calendar carries
those answers as functions of its own module, so a consumer asks any
calendar any question and never whether it can. The makers
(Calendrical.Calendar, Calendrical.Calendar.Shifted,
Calendrical.Calendar.Weeks, Calendrical.Calendar.Lunisolar and
Calendrical.Composite) implement the kernel from their options.
Summary
Types
The calendars additional_calendars/0 returns, by IXDTF identifier.
Super type of any date or time.
Specifies the type of a calendar.
Specifies the type of a calendar
All date fields are optional however many functions will require the presence of one or more - and often all - fields be present.
The error a question about a date returns: :invalid_date for a date the calendar does not have, or a Calendrical.MissingFieldsError for a date missing a field the question needs.
All date time fields are optional however many functions will require the presence of one or more - and often all - fields be present.
Specifies the day of a date as either a positive integer or nil.
Specifies the days of the week as integers.
A mapping of a day of the week ordinal to the localized string of the name of that day.
Specifies the year of a date as either a positive integer or nil.
The types of relationship between two Date.Range intervals
Represents the number of days since the calendar epoch.
Boolean indicating is this is a leap month
Specifies the month of a date as either a positive integer or nil.
All naive date time fields are optional however many functions will require the presence of one or more - and often all - fields be present.
The part of a date, time or datetime that can be localized.
The precision for date intervals
Specifies the quadrimester (third) of year for a calendar date.
Specifies the quarter of year for a calendar date.
Specifies the semester (half) of year for a calendar date.
All time fields are optional however many functions will require the presence of one or more - and often all - fields be present.
A traditional lunisolar month: its number in the traditional
numbering, or that number and :leap for a leap month.
Specifies the week of year for a calendar date.
Specifies the year of a date as either a positive integer or nil.
Callbacks
Returns the date of this calendar that falls on an ISO day number:
the reverse of date_to_iso_days/3.
Returns the date of this calendar that written figures name: the
inverse of written_date/3.
Returns the ISO day number of a date of this calendar: the count of
days from Calendrical's epoch that date_from_iso_days/1 reverses.
Returns the whole number of years, quarters, months, weeks or days
from one {year, month, day} to another, as shift/6 adds them.
Returns the static facts about this calendar, as Calendrical.Info.t/0.
Returns the position of a year's leap month, or nil where the year
has none.
Returns the date a specified positive or negative integer number of
periods (years, quarters, months, weeks or days) from a
{year, month, day} of this calendar.
Returns the figures a date is written with: the year, the month and
the day a format prints with y, M and d.
Functions
Returns every calendar Calendrical implements that no CLDR calendar type
resolves to, as a %{atom => module} map keyed by its IXDTF [u-ca=…]
identifier.
Returns a calendar configured according to the preferences defined for a territory.
Returns the Calendrical calendar module associated with a CLDR calendar type.
Returns the calendar module for a locale.
Returns the calendar module preferred for a territory.
Returns a boolean indicating if a module
is a Calendrical module.
Converts a date or a date range to another calendar.
Returns the current date or date range for a date period (year, quarter, month, week or day).
Returns the cycle year
number for a date.
Returns the cyclic year data for a locale and calendar type.
Returns a Calendar.date/0 from a year, day_of_year
and a calendar.
Returns a date represented by a number of days since the start of the epoch.
Returns a Calendar.date/0 from a keyword list
and a calendar.
Returns a Calendar.date/0 from a date tuple of
{year, month, day} and a calendar.
Returns the number of days since the start of the epoch.
Formats a date into a string representation.
Returns the dates in calendar, of the given month and day, that fall
within the given Gregorian year.
Returns the DateTime (defaulting to UTC timezone) for the given Modified Julian Day.
Returns the {day_of_era, era} for
a date.
Returns the day of the week for a date.
Returns the day of the week for a date with the week starting on a given day.
Returns the day of the year
for a date.
Returns the day period data for a locale and calendar type.
Returns the day name data for a locale and calendar type.
Returns the number of days in the month of a date.
Returns the default calendar.
Returns the whole number of years, quarters, months, weeks or days from one date to another, in the dates' own calendar.
Returns the era data for a locale and calendar type.
Returns the extended year of a date: one number for its year that runs on through every era of its calendar.
Returns the first day of a week for a given
locale where 1 means Monday and 7 means Sunday.
Returns the first day of the week for a given territory.
Returns the first date of a year
for a Calendar.date/0.
Returns the first date of a year
in a calendar.
Returns the gregorian date of the first day of a year
for a calendar.
Returns the gregorian date of the first day of a year
for a calendar.
Returns the cardinal day number representing Friday.
An inspect_fun/2 that can be configured in
Inspect.Opts supporting inspection of user-defined
calendars.
Returns an Enumerable list of dates of a given precision
of either :years, :quarters, :months, :weeks or
:days.
Returns an a Stream function than can be lazily
enumerated.
Returns the ISO day of week for a date
where 1 means Monday and 7 means
Sunday.
Returns the day of the week for a given
iso_day_number
Returns the ISO week number for
a date.
Returns the last date of a year
for a Calendar.date/0.
Returns the last date of a year
for a calendar.
Returns the gregorian date of the last day of a year
for a calendar.
Returns the gregorian date of the last day of a year
for a calendar.
Localize a date by converting it to the calendar introspected from the current process locale.
Localize a date by converting it to calendar introspected from the provided or default locale.
Returns a localized string for a part of
a Calendar.date/0.
Returns the minimum days in the first week of a year for a given locale.
Returns the minimum days in the first week of a year for a given territory.
Returns the Modified Julian Day of
a Calendar.date/0.
Returns the cardinal day number representing Monday.
Returns a sorted list of tuples containing ordinal months and month names for a give calendar.
Returns the month number for
a date.
Returns the month pattern data for a locale and calendar type.
Returns the month name data for a locale and calendar type.
Returns the number of months in the year of a date.
Returns the days of a named month in a year, in the order of time.
Creates a new proleptic Gregorian calendar based upon the provided configuration.
Returns the next date or date range for a date period (year, quarter, month, week or day).
Parses a locale-formatted string as a date, time, datetime, or date range —
whichever matches. Delegates to Localize.DateTime.Parser.parse/2.
Returns the previous date or date range for a date period (year, quarter, month, week or day).
Returns the quarter number for
a date.
Returns the quarter name data for a locale and calendar type.
Returns the related gregorian year
number for a date.
Returns the cardinal day number representing Saturday.
Formats a date, time or datetime with Calendar.strftime/3, naming its
month, day of the week and day period in a locale.
Formats a date, time or datetime with Calendar.strftime/3, naming its
month, day of the week and day period in a locale, or raises.
Returns a keyword list of options than can be applied to
Calendar.strftime/3.
Returns the cardinal day number representing Sunday.
Returns the list of CLDR calendar types supported by Calendrical.
Returns the cardinal day number representing Thursday.
Returns a year's months in order, named traditionally, with any leap month among them.
Returns a year's months in order, named traditionally, with any leap month among them.
Returns the cardinal day number representing Tuesday.
Validates if the argument is a Calendrical calendar module.
Returns the cardinal day number representing Wednesday.
Returns the {month, week_number} for a date: the month the date's week belongs to and the week's number in it.
Returns the {year, week_number}
for a date.
Returns whether a given date is a weekday.
Returns a list of the days of the week that are considered a weekend for a given territory (country).
Returns a list of the days of the week that are considered a weekend for a given territory (region, country).
Returns whether a given date is a weekend day.
Returns the number of weeks in a year.
Returns the number of weeks in a year for
a calendar.
Returns the number of whole days in n weeks.
Returns the {year_of_era, era} for
a date.
Types
@type additional_calendars() :: %{
iso8601: Calendrical.ISO,
iso_week: Calendrical.ISOWeek,
julian: Calendrical.Julian,
julian_dec25: Calendrical.Julian.Dec25,
julian_jan1: Calendrical.Julian.Jan1,
julian_march1: Calendrical.Julian.March1,
julian_march25: Calendrical.Julian.March25,
julian_sept1: Calendrical.Julian.Sept1,
lunar_japanese: Calendrical.LunarJapanese,
nrf: Calendrical.NRF,
reform_england: Calendrical.Reform.England,
reform_japan: Calendrical.Reform.Japan,
reform_sweden: Calendrical.Reform.Sweden,
reform_sweden_transitional: Calendrical.Reform.Sweden.Transitional,
vietnamese: Calendrical.Vietnamese
}
The calendars additional_calendars/0 returns, by IXDTF identifier.
@type any_date_time() :: date() | time() | naive_date_time() | date_time()
Super type of any date or time.
@type calendar() :: module() | nil
Specifies the type of a calendar.
A calendar is a module that implements
the Calendar and Calendrical
behaviours. Calendar functions will
default to Calendrical.Gregorian
in most cases.
@type calendar_type() :: :month | :week
Specifies the type of a calendar
@type date() :: %{ optional(:year) => year(), optional(:month) => month(), optional(:day) => day(), optional(:calendar) => calendar(), optional(any()) => any() }
All date fields are optional however many functions will require the presence of one or more - and often all - fields be present.
@type date_error() :: {:error, Exception.t()}
The error a question about a date returns: :invalid_date for a date the calendar does not have, or a Calendrical.MissingFieldsError for a date missing a field the question needs.
@type date_time() :: %{ optional(:calendar) => calendar(), optional(:day) => day(), optional(:hour) => Calendar.hour(), optional(:microsecond) => Calendar.microsecond(), optional(:minute) => Calendar.minute(), optional(:month) => month(), optional(:second) => Calendar.second(), optional(:std_offset) => Calendar.std_offset(), optional(:time_zone) => Calendar.time_zone(), optional(:utc_offset) => Calendar.utc_offset(), optional(:year) => year(), optional(:zone_abbr) => Calendar.zone_abbr(), optional(any()) => any() }
All date time fields are optional however many functions will require the presence of one or more - and often all - fields be present.
@type day() :: Calendar.day() | nil
Specifies the day of a date as either a positive integer or nil.
@type day_of_week() :: 1..7
Specifies the days of the week as integers.
Days of the week are encoded as the integers 1 through
7 with 1 representing Monday and 7 representing Sunday.
Note that a calendar can be configured to start
on any day of the week. day_of_week is only a
way of encoding the days as an integer.
@type day_of_week_to_binary() :: {day_of_week(), String.t()}
A mapping of a day of the week ordinal to the localized string of the name of that day.
@type era() :: non_neg_integer() | nil
Specifies the year of a date as either a positive integer or nil.
@type interval_relation() ::
:precedes
| :preceded_by
| :meets
| :met_by
| :overlaps
| :overlapped_by
| :finished_by
| :finishes
| :contains
| :during
| :starts
| :started_by
| :equals
The types of relationship between two Date.Range intervals
@type iso_day_number() :: integer()
Represents the number of days since the calendar epoch.
The Calendar epoch is 0000-01-01
in the proleptic gregorian calendar.
@type leap_month?() :: boolean() | :leap
Boolean indicating is this is a leap month
@type month() :: Calendar.month() | nil
Specifies the month of a date as either a positive integer or nil.
@type naive_date_time() :: %{ optional(:calendar) => calendar(), optional(:day) => day(), optional(:hour) => Calendar.hour(), optional(:microsecond) => Calendar.microsecond(), optional(:minute) => Calendar.minute(), optional(:month) => month(), optional(:second) => Calendar.second(), optional(:year) => year(), optional(any()) => any() }
All naive date time fields are optional however many functions will require the presence of one or more - and often all - fields be present.
@type part() ::
:day_periods
| :day_period
| :days_of_week
| :day_of_week
| :month
| :quarter
| :cyclic_year
| :era
The part of a date, time or datetime that can be localized.
@type precision() :: :years | :quarters | :months | :weeks | :days
The precision for date intervals
@type quadrimester() :: 1..3
Specifies the quadrimester (third) of year for a calendar date.
@type quarter() :: 1..4
Specifies the quarter of year for a calendar date.
@type semester() :: 1..2
Specifies the semester (half) of year for a calendar date.
@type time() :: %{ optional(:calendar) => Calendar.calendar(), optional(:hour) => Calendar.hour(), optional(:microsecond) => Calendar.microsecond(), optional(:minute) => Calendar.minute(), optional(:second) => Calendar.second(), optional(any()) => any() }
All time fields are optional however many functions will require the presence of one or more - and often all - fields be present.
@type traditional_month() :: Calendar.month() | {Calendar.month(), :leap}
A traditional lunisolar month: its number in the traditional
numbering, or that number and :leap for a leap month.
@type week() :: pos_integer()
Specifies the week of year for a calendar date.
@type year() :: Calendar.year() | nil
Specifies the year of a date as either a positive integer or nil.
Callbacks
@callback date_from_iso_days(iso_day_number :: iso_day_number()) :: {Calendar.year(), Calendar.month(), Calendar.day()}
Returns the date of this calendar that falls on an ISO day number:
the reverse of date_to_iso_days/3.
@callback date_from_written_date( year :: Calendar.year(), month :: traditional_month(), day :: Calendar.day() ) :: {:ok, {Calendar.year(), Calendar.month(), Calendar.day()}} | {:error, :invalid_date}
Returns the date of this calendar that written figures name: the
inverse of written_date/3.
Figures that name no date are {:error, :invalid_date}. The reason is
an atom, not an exception as Calendrical's other functions return,
because Localize's date parser reads it from every calendar.
@callback date_to_iso_days(year :: year(), month :: month(), day :: day()) :: iso_day_number()
Returns the ISO day number of a date of this calendar: the count of
days from Calendrical's epoch that date_from_iso_days/1 reverses.
Every calendar's arithmetic runs through this pair, and use Calendrical.Calendar refuses to compile a calendar without them.
@callback diff( from :: {year(), month() | week(), day()}, to :: {year(), month() | week(), day()}, date_part :: :years | :quarters | :months | :weeks | :days ) :: integer() | {:error, Exception.t()}
Returns the whole number of years, quarters, months, weeks or days
from one {year, month, day} to another, as shift/6 adds them.
The count is the largest number of date_parts that shift/6, clamping
the day into a shorter month, can add to the earlier date without
passing the later one; it is negative when to is before from.
A {year, month, day} that is no date of the calendar is
{:error, %Calendrical.InvalidDateError{}}, one missing a field a
Calendrical.MissingFieldsError, and a date_part other than the five
a Calendrical.InvalidPartError.
@callback info() :: Calendrical.Info.t()
Returns the static facts about this calendar, as Calendrical.Info.t/0.
The facts are what a calendar is: the CLDR calendars that name its months and its eras, its epoch, whether it has a year 0, what its year is built of, the fewest and most months a year has, the rule its own weeks follow, its cycles, the place it is reckoned at, the lengths its months can have, the calendar its dates are parsed in and, for a composite, its member calendars. Every calendar Calendrical builds answers it.
@callback leap_month(year :: year()) :: Calendar.month() | nil
Returns the position of a year's leap month, or nil where the year
has none.
It is the one fact the traditional numbering of months rests on: a
month before the leap month keeps its number, the leap month is
{number, :leap} of the month it follows, and a month after it is
one less than its position. In a Chinese year whose leap month follows
month 2 it is 3, so position 3 is {2, :leap} and position 4 is 3; in
a Hebrew leap year it is 6, Adar I, {5, :leap}.
@callback shift( year :: year(), month :: month() | week(), day :: day(), date_part :: :years | :quarters | :months | :weeks | :days, increment :: integer(), options :: Keyword.t() ) :: {Calendar.year(), Calendar.month(), Calendar.day()} | {:error, Exception.t()}
Returns the date a specified positive or negative integer number of
periods (years, quarters, months, weeks or days) from a
{year, month, day} of this calendar.
Every calendar answers for each of the five periods. The :clamp
option says whether a month or a day the resulting year or month does
not have is brought back into it (true) or kept as it is counted
(false); where it is not given, the calendar's own default applies.
A {year, month, day} that is no date of the calendar is
{:error, %Calendrical.InvalidDateError{}}, one missing a field a
Calendrical.MissingFieldsError, and a date_part other than the five
a Calendrical.InvalidPartError.
@callback written_date(year :: year(), month :: month(), day :: day()) :: {Calendar.year(), traditional_month(), Calendar.day()}
Returns the figures a date is written with: the year, the month and
the day a format prints with y, M and d.
A calendar whose dates are written as its own fields answers them
unchanged, which is the default every calendar has and what the
Hebrew calendar answers, as ICU writes a Hebrew month by its place in
the year. A calendar whose dates are written as another calendar's
answers that calendar's: a fiscal year that begins in July writes its
month 1 as {gregorian_year, 7, day}, and Calendrical.Julian.March25
writes its month 1 day 1 as {label_year, 3, 25}. A lunisolar calendar
writes a month by its traditional number, {number, :leap} for a leap
month, so that CLDR's numeric leap pattern applies.
Functions
@spec additional_calendars() :: additional_calendars()
Returns every calendar Calendrical implements that no CLDR calendar type
resolves to, as a %{atom => module} map keyed by its IXDTF [u-ca=…]
identifier.
Most have no CLDR/BCP 47 calendar identifier: Julian and its year-start
variants, the reform calendars, NRF, ISO week dates, and the Vietnamese and
Japanese lunisolar calendars, which CLDR files under chinese. :iso8601,
which CLDR does define, is the Gregorian calendar with ISO 8601's week
rules, Calendrical.ISO. The identifiers are resolved by
calendar_from_cldr_calendar_type/1 ahead of the CLDR lookup, so consumers
that keep to CLDR identifiers are unaffected. An identifier is written with
hyphens in the suffix: :julian_march25 is [u-ca=julian-march25].
Returns
- A
%{atom => module}map of the additional calendar identifiers.
Examples
iex> Calendrical.additional_calendars()[:vietnamese]
Calendrical.Vietnamese
iex> Calendrical.additional_calendars()[:julian_march25]
Calendrical.Julian.March25
@spec calendar_for_territory(atom() | String.t(), Keyword.t()) :: {:ok, calendar()} | {:error, Exception.t()}
Returns a calendar configured according to the preferences defined for a territory.
Arguments
territoryis any valid ISO3166-2 code as anString.t/0or upcasedatom.configis a Keyword list defining the configuration of the calendar. The default is[].
Options
- The options of a
:monthcalendar ofCalendrical.new/3::base,:year_begins,:year_number,:written_year,:weeks,:cldr_calendar_type,:era_calendar_type,:parsing_calendarand:years_in_cycle. The territory's own week rule is the default:weeks.
Returns
{:ok, calendar_module}or{:error, exception}whereexceptionis an exception struct.
Examples
iex> Calendrical.calendar_for_territory(:US)
{:ok, Calendrical.US}
iex> {:error, %Localize.UnknownTerritoryError{}} = Calendrical.calendar_for_territory(:YY)
@spec calendar_from_cldr_calendar_type(atom() | String.t()) :: {:ok, module()} | {:error, Exception.t()}
Returns the Calendrical calendar module associated with a CLDR calendar type.
CLDR calendar types are the atoms (or their string
equivalents) returned by Localize.validate_calendar/1
and listed by supported_cldr_calendar_types/0. This
function maps such a type to the corresponding
Calendrical calendar module if it is loaded in the
current build.
The calendars in additional_calendars/0 resolve here too, ahead of the
CLDR lookup — every calendar Calendrical implements that no CLDR type
reaches, such as :vietnamese and :julian_march25 ("julian-march25"),
and :iso8601, the Gregorian calendar with ISO 8601's week rules.
This is the one table of names. A name has no territory, so :gregorian
is Calendrical.Gregorian and :chinese is Calendrical.Chinese; a
locale that names them in its -u-ca- extension has a territory, and
calendar_from_locale/1 refines those two by it.
Arguments
calendar_typeis a CLDR calendar type as an atom or string. The string"gregory"is accepted as an alias for:gregorian.
Returns
{:ok, calendar_module}wherecalendar_moduleis the Calendrical calendar module for the given CLDR calendar type, or{:error, exception}whereexceptionis an exception struct.
Examples
iex> Calendrical.calendar_from_cldr_calendar_type(:gregorian)
{:ok, Calendrical.Gregorian}
iex> Calendrical.calendar_from_cldr_calendar_type("gregory")
{:ok, Calendrical.Gregorian}
iex> Calendrical.calendar_from_cldr_calendar_type(:persian)
{:ok, Calendrical.Persian}
iex> Calendrical.calendar_from_cldr_calendar_type(:islamic_umalqura)
{:ok, Calendrical.Islamic.UmmAlQura}
iex> Calendrical.calendar_from_cldr_calendar_type(:ethiopic_amete_alem)
{:ok, Calendrical.Ethiopic.AmeteAlem}
iex> Calendrical.calendar_from_cldr_calendar_type(:dangi)
{:ok, Calendrical.Korean}
iex> Calendrical.calendar_from_cldr_calendar_type(:julian)
{:ok, Calendrical.Julian}
iex> Calendrical.calendar_from_cldr_calendar_type(:iso8601)
{:ok, Calendrical.ISO}
iex> Calendrical.calendar_from_cldr_calendar_type("vietnamese")
{:ok, Calendrical.Vietnamese}
iex> Calendrical.calendar_from_cldr_calendar_type("reform-england")
{:ok, Calendrical.Reform.England}
iex> {:error, %Localize.UnknownCalendarError{}} =
...> Calendrical.calendar_from_cldr_calendar_type(:not_a_calendar)
@spec calendar_from_locale(Localize.LanguageTag.t() | String.t() | atom()) :: {:ok, calendar()} | {:error, Exception.t()}
Returns the calendar module for a locale.
A locale's -u-ca-<name> extension names a CLDR calendar, and its
calendar module is the one calendar_from_cldr_calendar_type/1 gives
that name, refined by the locale where its territory says more than the
name: gregory is the territory's Gregorian calendar, with its weeks,
and chinese in Vietnam is Calendrical.Vietnamese. A locale with no
-u-ca- takes the calendar its territory prefers. This is the mapping
from a language tag's calendar to a calendar module: Localize does not
depend on Calendrical, so it is Calendrical's to give.
Arguments
localeis a locale identifier atom, string, or aLocalize.LanguageTag.t/0.
Returns
{:ok, calendar_module}, or{:error, exception}if the locale is not valid. A-u-ca-name that is not a CLDR calendar's, such as an identifier ofadditional_calendars/0, is not valid in a locale.
Examples
iex> Calendrical.calendar_from_locale("en-US")
{:ok, Calendrical.US}
iex> Calendrical.calendar_from_locale("en-GB-u-ca-gregory")
{:ok, Calendrical.GB}
iex> Calendrical.calendar_from_locale("fa-IR")
{:ok, Calendrical.Persian}
iex> Calendrical.calendar_from_locale("fa-IR-u-ca-gregory")
{:ok, Calendrical.IR}
iex> Calendrical.calendar_from_locale("en-u-ca-hebrew")
{:ok, Calendrical.Hebrew}
iex> Calendrical.calendar_from_locale("vi-u-ca-chinese")
{:ok, Calendrical.Vietnamese}
iex> {:error, %Localize.InvalidLocaleError{}} =
...> Calendrical.calendar_from_locale("en-u-ca-julian")
@spec calendar_from_territory(atom() | String.t()) :: {:ok, calendar()} | {:error, Exception.t()}
Returns the calendar module preferred for a territory.
Arguments
territoryis any valid ISO3166-2 code as anString.t/0or upcasedatom.
Returns
{:ok, calendar_module}or{:error, exception}whereexceptionis an exception struct.
Examples
iex> Calendrical.calendar_from_territory(:US)
{:ok, Calendrical.US}
iex> Calendrical.calendar_from_territory(:IR)
{:ok, Calendrical.Persian}
iex> {:error, %Localize.UnknownTerritoryError{}} = Calendrical.calendar_from_territory(:YY)Notes
The overwhelming majority of territories have
:gregorian as their first preferred calendar
and therefore Calendrical.Gregorian or
a derivation of it will be returned for most
territories.
A territory that prefers another calendar is given
that calendar's module: Iran (territory :IR) prefers
the :persian calendar, so Calendrical.Persian is
returned, and Thailand (:TH) the :buddhist
calendar, so Calendrical.Buddhist is.
Returns a boolean indicating if a module
is a Calendrical module.
A calendar is a module that implements Elixir's Calendar behaviour
and the Calendrical behaviour, and says so with @behaviour. That
is all that is asked of it here: what the module then answers for
each callback is its author's to keep.
Arguments
moduleis any module name as anatom.
Returns
trueifmoduleis a calendar module that implements theCalendarandCalendricalbehaviours, otherwisefalse.
Examples
iex> Calendrical.calendar_module?(Calendrical.Gregorian)
true
iex> Calendrical.calendar_module?(Calendar.ISO)
false
iex> Calendrical.calendar_module?(Enum)
false
@spec convert(Date.t() | Date.Range.t(), Calendar.calendar()) :: {:ok, Date.t() | Date.Range.t()} | {:error, Exception.t()}
Converts a date or a date range to another calendar.
If the argument is a Calendar.date/0, Date.convert/2 is used to
do the conversion.
If the argument is a Date.Range.t/0 then Date.convert/2 is
applied to the start and end of the range and a new range returned.
Arguments
date_or_rangeis anyCalendar.date/0orDate.Range.t/0.calendaris any valid calendar module.
Returns
{:ok, converted_date_or_range}or{:error, %Calendrical.IncompatibleCalendarError{}}where the two calendars begin their days at different times.
Examples
iex> Calendrical.convert(~D[2024-06-01], Calendrical.Hebrew)
{:ok, ~D[5784-09-24 Calendrical.Hebrew]}
iex> Calendrical.convert(Date.range(~D[2024-06-01], ~D[2024-06-03]), Calendrical.Persian)
{:ok, Date.range(~D[1403-03-12 Calendrical.Persian], ~D[1403-03-14 Calendrical.Persian])}
@spec current(date() | Date.Range.t(), :year | :quarter | :month | :week | :day) :: date() | Date.Range.t()
Returns the current date or date range for a date period (year, quarter, month, week or day).
Arguments
date_or_date_rangeis anyCalendar.date/0orDate.Range.t/0.periodis:year,:quarter,:month,:weekor:day.
Returns
When a Calendar.date/0 is passed, a Calendar.date/0 is
returned. When a Date.Range.t/0 is passed
a Date.Range.t/0 is returned.
Examples
iex> Calendrical.current(~D[2019-01-01], :day)
~D[2019-01-01]
@spec cyclic_year(date()) :: Calendar.year() | date_error()
Returns the cycle year
number for a date.
A related gregorian year is the gregorian year that is most closely associated with a date that is in another calendar.
Arguments
dateis anyCalendar.date/0or a map with one or more of the fields:year,:month,:dayand optionally:calendar.
Returns
- the cyclic year as an integer.
Examples
iex> Calendrical.cyclic_year(~D[2019-01-01])
2019
iex> Calendrical.cyclic_year(Calendrical.first_day_of_year(2019, Calendrical.NRF))
2019
iex> Calendrical.cyclic_year(Calendrical.last_day_of_year(2019, Calendrical.NRF))
2019
@spec cyclic_years(Localize.LanguageTag.t() | String.t() | atom(), atom()) :: {:ok, map()} | {:error, Exception.t()}
Returns the cyclic year data for a locale and calendar type.
Arguments
localeis a locale identifier atom, string, or aLocalize.LanguageTag.t/0. The default isLocalize.get_locale/0.calendaris a calendar type atom. The default is:gregorian.
Returns
{:ok, map}where the map holds the cyclic year data.{:error, exception}if the locale has no cyclic year data for the calendar.
Examples
iex> {:ok, cyclic_years} = Calendrical.cyclic_years(:en, :chinese)
iex> cyclic_years.years.format.abbreviated[1]
"jia-zi"
@spec date_from_day_of_year(Calendar.year(), pos_integer(), calendar()) :: Date.t() | {:error, Exception.t()}
Returns a Calendar.date/0 from a year, day_of_year
and a calendar.
Arguments
yearis any integer year that is valid incalendar.day_of_yearis any valid ordinal day ofyear.calendaris any module implementing theCalendarandCalendricalbehaviours. The default isCalendrical.Gregorian.
Returns
a
Calendar.date/0or{:error, %Calendrical.InvalidDateError{}}for a date the calendar does not have.
Examples
iex> Calendrical.date_from_day_of_year(2019, 32)
~D[2019-02-01 Calendrical.Gregorian]
iex> Calendrical.date_from_day_of_year(2019, 366)
{:error, %Calendrical.InvalidDateError{calendar: Calendrical.Gregorian, value: [year: 2019, day_of_year: 366]}}
iex> Calendrical.date_from_day_of_year(1700, 1, Calendrical.Julian.March25)
~D[1700-01-01 Calendrical.Julian.March25]
@spec date_from_iso_days(Calendar.iso_days() | iso_day_number(), calendar()) :: Date.t() | {:error, Exception.t()}
Returns a date represented by a number of days since the start of the epoch.
The start of the epoch is the date
0000-01-01.
Arguments
iso_daysis an integer representing the number of days since the start of the epoch.calendaris any module that implements theCalendarandCalendricalbehaviours.
Returns
Examples
iex> Calendrical.date_from_iso_days(737425, Calendar.ISO)
~D[2019-01-01]
iex> Calendrical.date_from_iso_days(366, Calendar.ISO)
~D[0001-01-01]
iex> Calendrical.date_from_iso_days(0, Calendar.ISO)
~D[0000-01-01]
@spec date_from_list(Keyword.t(), calendar()) :: Date.t() | {:error, Exception.t()}
Returns a Calendar.date/0 from a keyword list
and a calendar.
Arguments
[year: year, month: month, day: day}is a keyword list representing a date.calendaris any module implementing theCalendarandCalendricalbehaviours. The default isCalendrical.Gregorian.
Returns
a
Calendar.date/0or{:error, %Calendrical.InvalidDateError{}}for a date the calendar does not have.
Examples
iex> Calendrical.date_from_list([year: 2019, month: 3, day: 25], Calendrical.Gregorian)
%Date{calendar: Calendrical.Gregorian, day: 25, month: 3, year: 2019}
iex> Calendrical.date_from_list([year: 2019, month: 2, day: 29], Calendrical.Gregorian)
{:error, %Calendrical.InvalidDateError{calendar: Calendrical.Gregorian, value: {2019, 2, 29}}}
@spec date_from_tuple({Calendar.year(), Calendar.month(), Calendar.day()}, calendar()) :: Date.t() | {:error, Exception.t()}
Returns a Calendar.date/0 from a date tuple of
{year, month, day} and a calendar.
Arguments
{year, month, day}is a tuple representing a date.calendaris any module implementing theCalendarandCalendricalbehaviours. The default isCalendrical.Gregorian.
Returns
Examples
iex> Calendrical.date_from_tuple({2019, 3, 25}, Calendrical.Gregorian)
%Date{calendar: Calendrical.Gregorian, day: 25, month: 3, year: 2019}
iex> Calendrical.date_from_tuple({2019, 2, 29}, Calendrical.Gregorian)
{:error, %Calendrical.InvalidDateError{calendar: Calendrical.Gregorian, value: {2019, 2, 29}}}
@spec date_to_iso_days(Date.t()) :: iso_day_number()
Returns the number of days since the start of the epoch.
The start of the epoch is the date 0000-01-01.
Arguments
dateis anyCalendar.date/0.
Returns
- The integer number of days since the epoch
for the given
date.
Examples
iex> Calendrical.date_to_iso_days(~D[2019-01-01])
737425
iex> Calendrical.date_to_iso_days(~D[0001-01-01])
366
iex> Calendrical.date_to_iso_days(~D[0000-01-01])
0
Formats a date into a string representation.
Note that the output is not decorated with the calendar module name.
Arguments
dateis anyCalendar.date/0.
Returns
- The date as a string, in the calendar's own format.
Examples
iex> Calendrical.date_to_string(~D[2019-12-04])
"2019-12-04"
iex> Calendrical.date_to_string(~D[2019-06-04 Calendrical.NRF])
"2019-06-04"
@spec dates_in_gregorian_year( module(), Calendar.year(), Calendar.month(), Calendar.day() ) :: [Date.t()]
Returns the dates in calendar, of the given month and day, that fall
within the given Gregorian year.
This dispatches the calendar's own dates_in_gregorian_year/3, so a
calendar that overrides the default implementation answers here too; use
this arity when the calendar is chosen at runtime.
Arguments
calendaris a module implementing theCalendricalbehaviour.gregorian_yearis the Gregorian year to search within.monthanddayare a month and day incalendar.
Returns
- A list of zero, one or two
Date.t/0values incalendar, earliest first. A calendar date recurs once per that calendar's own year, but the calendar and Gregorian years drift, so a Gregorian year can hold zero, one or two occurrences of it.
Examples
iex> Calendrical.dates_in_gregorian_year(Calendrical.Islamic.Civil, 2025, 1, 1)
[~D[1447-01-01 Calendrical.Islamic.Civil]]
# Ramadan 29 falls twice in the Gregorian year 2000
iex> Calendrical.dates_in_gregorian_year(Calendrical.Islamic.Civil, 2000, 9, 29)
[~D[1420-09-29 Calendrical.Islamic.Civil], ~D[1421-09-29 Calendrical.Islamic.Civil]]
@spec datetime_from_modified_julian_date(number()) :: DateTime.t()
Returns the DateTime (defaulting to UTC timezone) for the given Modified Julian Day.
Arguments
mjdis a number representing days passed since November 17, 1858 (Julian Calendar).
Returns
- a
DateTime.t/0at UTC timezone.
Examples
iex> Calendrical.datetime_from_modified_julian_date(59848)
~U[2022-09-26 00:00:00.000Z]
iex> Calendrical.datetime_from_modified_julian_date(59848.75)
~U[2022-09-26 18:00:00.000Z]
@spec day_of_era(date()) :: {Calendar.day(), Calendar.era()} | date_error()
Returns the {day_of_era, era} for
a date.
Arguments
dateis anyCalendar.date/0or a map with one or more of the fields:year,:month,:dayand optionally:calendar.
Returns
- The day of the era, counted from its first day, and the era of the date's calendar year, as a tuple. A calendar whose year 1 begins on another day than 1 January AD 1 counts era 1 from the day it does: NRF's year 1 began 34 days into AD 1.
Examples
iex> Calendrical.day_of_era ~D[2019-01-01]
{737060, 1}
iex> Calendrical.day_of_era(Calendrical.first_day_of_year(2019, Calendrical.NRF))
{737059, 1}
iex> Calendrical.day_of_era(Calendrical.last_day_of_year(2019, Calendrical.NRF))
{737422, 1}
@spec day_of_week(date()) :: Calendar.day_of_week()
Returns the day of the week for a date.
Delegates to Date.day_of_week/1.
Arguments
dateis anyCalendar.date/0.
Returns
- An integer day of the week where
1meansMondayand7meansSunday.
Examples
iex> Calendrical.day_of_week(~D[2026-07-05])
7
@spec day_of_week(date(), atom()) :: Calendar.day_of_week()
Returns the day of the week for a date with the week starting on a given day.
Delegates to Date.day_of_week/2.
Arguments
dateis anyCalendar.date/0.starting_onis:defaultor an atom day name such as:mondayor:sunday. SeeDate.day_of_week/2.
Returns
- An integer day of the week relative to
starting_on.
Examples
iex> Calendrical.day_of_week(~D[2026-07-05], :sunday)
1
@spec day_of_year(date()) :: Calendar.day() | date_error()
Returns the day of the year
for a date.
Arguments
dateis anyCalendar.date/0or a map with one or more of the fields:year,:month,:dayand optionally:calendar.
Returns
- The day of the year as an integer, counting the year's first day as 1.
Examples
iex> Calendrical.day_of_year(~D[2019-01-01])
1
iex> Calendrical.day_of_year(~D[2016-12-31])
366
iex> Calendrical.day_of_year(~D[2019-12-31])
365
iex> Calendrical.day_of_year(~D[2019-W52-7 Calendrical.NRF])
364
iex> Calendrical.day_of_year(~D[2012-W53-7 Calendrical.NRF])
371
@spec day_periods(Localize.LanguageTag.t() | String.t() | atom(), atom()) :: {:ok, map()} | {:error, Exception.t()}
Returns the day period data for a locale and calendar type.
Arguments
localeis a locale identifier atom, string, or aLocalize.LanguageTag.t/0. The default isLocalize.get_locale/0.calendaris a calendar type atom. The default is:gregorian.
Returns
{:ok, map}where the map holds the day period data.{:error, exception}if the locale has no day period data for the calendar.
Examples
iex> {:ok, day_periods} = Calendrical.day_periods(:en, :gregorian)
iex> day_periods.format.abbreviated.noon
"noon"
@spec days(Localize.LanguageTag.t() | String.t() | atom(), atom()) :: {:ok, map()} | {:error, Exception.t()}
Returns the day name data for a locale and calendar type.
Arguments
localeis a locale identifier atom, string, or aLocalize.LanguageTag.t/0. The default isLocalize.get_locale/0.calendaris a calendar type atom. The default is:gregorian.
Returns
{:ok, map}where the map holds the day name data.{:error, exception}if the locale has no day name data for the calendar.
Examples
iex> {:ok, days} = Calendrical.days(:en, :gregorian)
iex> days.format.wide[1]
"Monday"
@spec days_in_month(date()) :: Calendar.day() | {:error, Exception.t()}
Returns the number of days in the month of a date.
Delegates to Date.days_in_month/1. A month of a calendar of weeks is four or five weeks, as its pattern of weeks gives it, and its last month has one week more in a year of 53 weeks.
Arguments
dateis anyCalendar.date/0.
Returns
The number of days in the month of
date, or{:error, exception}for a date whose month its year does not have.
Examples
iex> Calendrical.days_in_month(~D[2026-07-05])
31
iex> Calendrical.days_in_month(~D[2026-06-16 Calendrical.ISOWeek])
28
@spec default_calendar() :: Calendrical.Gregorian
Returns the default calendar.
Returns
- The default calendar module,
Calendrical.Gregorian.
Examples
iex> Calendrical.default_calendar()
Calendrical.Gregorian
@spec diff( Calendar.date(), Calendar.date(), :years | :quarters | :months | :weeks | :days ) :: integer() | {:error, Exception.t()}
Returns the whole number of years, quarters, months, weeks or days from one date to another, in the dates' own calendar.
diff/3 is the inverse of adding periods to a date: the count is the
largest number of date_parts that can be added to the earlier date —
a day that a shorter month lacks becoming that month's last day, as
Date.shift/2 does — without passing the later date, and it is negative
when date_to is before date_from. Date.diff/2 answers the same
question in days.
Arguments
date_fromanddate_toareCalendar.date/0values in the same calendar. ACalendar.ISOdate counts as aCalendrical.Gregorianone.date_partis one of:years,:quarters,:months,:weeksor:days.
Returns
The whole number of
date_parts fromdate_fromtodate_to, as an integer.{:error, %Calendrical.IncompatibleCalendarError{}}when the dates are in different calendars.{:error, %Calendrical.InvalidPartError{}}whendate_partis not one of the five.{:error, %Calendrical.MissingFieldsError{}}when a date lacks a year, month or day, and{:error, %Calendrical.InvalidCalendarModuleError{}}when its calendar is not a Calendrical calendar.
Examples
iex> Calendrical.diff(~D[2026-01-01], ~D[2027-04-01], :months)
15
iex> Calendrical.diff(~D[2026-01-01], ~D[2027-04-01], :years)
1
iex> Calendrical.diff(~D[2027-04-01], ~D[2026-01-01], :months)
-15
iex> Calendrical.diff(~D[2026-01-31], ~D[2026-02-28], :months)
1A Hebrew leap year has thirteen months:
iex> {:ok, from} = Date.new(5784, 1, 1, Calendrical.Hebrew)
iex> {:ok, to} = Date.new(5786, 1, 1, Calendrical.Hebrew)
iex> Calendrical.diff(from, to, :months)
25
@spec eras(Localize.LanguageTag.t() | String.t() | atom(), atom()) :: {:ok, map()} | {:error, Exception.t()}
Returns the era data for a locale and calendar type.
Arguments
localeis a locale identifier atom, string, or aLocalize.LanguageTag.t/0. The default isLocalize.get_locale/0.calendaris a calendar type atom. The default is:gregorian.
Returns
{:ok, map}where the map holds the era data.{:error, exception}if the locale has no era data for the calendar.
Examples
iex> {:ok, eras} = Calendrical.eras(:en, :gregorian)
iex> eras.wide[1]
"Anno Domini"
@spec extended_year(date()) :: Calendar.year() | date_error()
Returns the extended year of a date: one number for its year that runs on through every era of its calendar.
It is the year TR35's u format symbol writes, and is the calendar's own year in every calendar but those that count back from an era: the Julian calendar has no year 0, so its 1 BC, year -1, has the extended year 0.
Arguments
dateis anyCalendar.date/0or a map with one or more of the fields:year,:month,:dayand optionally:calendar.
Returns
- The extended year as an integer.
Examples
iex> Calendrical.extended_year(~D[2019-01-01])
2019
iex> Calendrical.extended_year(Calendrical.last_day_of_year(2019, Calendrical.NRF))
2019
iex> Calendrical.extended_year(~D[-0001-06-15 Calendrical.Julian])
0
@spec first_day_for_locale(Localize.LanguageTag.t() | String.t() | atom()) :: day_of_week() | {:error, Exception.t()}
Returns the first day of a week for a given
locale where 1 means Monday and 7 means Sunday.
Note that the first day of the first week is commonly not aligned with the first day of the year.
Arguments
localeis any locale or locale name validated byLocalize.validate_locale/1.
Returns
The first day of the week for the territory associated with
localewhere1meansMondayand7meansSundayor{:error, exception}whereexceptionis an exception struct.
Examples
iex> Calendrical.first_day_for_locale(:en)
7
iex> Calendrical.first_day_for_locale("en-GB")
1
@spec first_day_for_territory(atom() | String.t()) :: day_of_week() | {:error, Exception.t()}
Returns the first day of the week for a given territory.
Arguments
territoryis any valid ISO3166-2 code.
Returns
The first day of the week for this territory where
1meansMondayand7meansSundayor{:error, exception}whereexceptionis an exception struct.
Examples
iex> Calendrical.first_day_for_territory(:US)
7
iex> Calendrical.first_day_for_territory("GB")
1
@spec first_day_of_year(date :: date()) :: Date.t() | {:error, Exception.t()}
Returns the first date of a year
for a Calendar.date/0.
Arguments
dateis anyCalendar.date/0.
Returns
a
Calendar.date/0or{:error, %Calendrical.InvalidDateError{}}for a date the calendar does not have.
Examples
iex> Calendrical.first_day_of_year(~D[2019-12-01])
~D[2019-01-01]
@spec first_day_of_year(year :: year(), calendar :: calendar()) :: Date.t() | {:error, Exception.t()}
Returns the first date of a year
in a calendar.
Arguments
yearis any year.calendaris any module that implements theCalendarandCalendricalbehaviours.
Returns
a
Calendar.date/0or{:error, %Calendrical.InvalidDateError{}}for a date the calendar does not have.
Examples
iex> Calendrical.first_day_of_year(2019, Calendrical.Gregorian)
%Date{calendar: Calendrical.Gregorian, day: 1, month: 1, year: 2019}
iex> Calendrical.first_day_of_year(2019, Calendrical.NRF)
%Date{calendar: Calendrical.NRF, day: 1, month: 1, year: 2019}
iex> Calendrical.first_day_of_year(1700, Calendrical.Julian.March25)
~D[1700-01-01 Calendrical.Julian.March25]
@spec first_gregorian_day_of_year(date()) :: Date.t() | {:error, Exception.t()}
Returns the gregorian date of the first day of a year
for a calendar.
Arguments
yearis any integer year number.calendaris any module that implements theCalendarandCalendricalbehaviours orCalendar.ISO.
Returns
The
Date.t/0of the first day of the year: inCalendrical.Gregorianfor ayearandcalendar, and in the date's own calendar for a date.{:error, %Calendrical.InvalidDateError{}}if the calendar has no such year.
Examples
iex> Calendrical.first_gregorian_day_of_year(2019, Calendrical.Gregorian)
%Date{calendar: Calendrical.Gregorian, day: 1, month: 1, year: 2019}
iex> Calendrical.first_gregorian_day_of_year(2019, Calendrical.NRF)
%Date{calendar: Calendrical.Gregorian, day: 3, month: 2, year: 2019}
iex> Calendrical.first_gregorian_day_of_year(~D[2019-12-01])
~D[2019-01-01]
@spec first_gregorian_day_of_year(year(), calendar()) :: Date.t() | {:error, Exception.t()}
Returns the gregorian date of the first day of a year
for a calendar.
Arguments
yearis any integer year number.calendaris any module that implements theCalendarandCalendricalbehaviours orCalendar.ISO.
Returns
A
Date.t/0in theCalendrical.Gregoriancalendar or{:error, %Calendrical.InvalidDateError{}}.
Examples
iex> Calendrical.first_gregorian_day_of_year(2019, Calendrical.Gregorian)
%Date{calendar: Calendrical.Gregorian, day: 1, month: 1, year: 2019}
iex> Calendrical.first_gregorian_day_of_year(2019, Calendrical.NRF)
%Date{calendar: Calendrical.Gregorian, day: 3, month: 2, year: 2019}
iex> Calendrical.first_gregorian_day_of_year(5786, Calendrical.Hebrew)
~D[2025-09-23 Calendrical.Gregorian]
@spec friday() :: 5
Returns the cardinal day number representing Friday.
Returns
5.
Examples
iex> Calendrical.friday()
5
@spec inspect(term(), list()) :: Inspect.Algebra.t()
An inspect_fun/2 that can be configured in
Inspect.Opts supporting inspection of user-defined
calendars.
This function can be configured in IEx for Elixir version 1.9
and later by:
IEx.configure(inspect: [inspect_fun: &Calendrical.inspect/2])
:okArguments
termis any term.optionsis a keyword list of options or anInspect.Opts.t/0.
Options
- The options of
Inspect.Opts.t/0.
Returns
- The
Inspect.Algebra.t/0document forterm, which renders a date or range of any calendar in its sigil form.
Examples
iex> ~D[2019-12-04 Calendrical.NRF]
...> |> Calendrical.inspect([])
...> |> Inspect.Algebra.format(80)
...> |> IO.iodata_to_binary()
"~D[2019-12-04 Calendrical.NRF]"
@spec interval( date_from :: Date.t(), date_to_or_count :: Date.t() | non_neg_integer(), precision() ) :: [Date.t()]
Returns an Enumerable list of dates of a given precision
of either :years, :quarters, :months, :weeks or
:days.
Arguments
date_fromis a anyCalendar.date/0that is the start of the sequence.date_to_or_countis upper bound of the sequence as aCalendar.date/0or the number of dates in the sequence to be generated.precisionis one of:years,:quarters,:months,:weeksor:days.
The sequence is generated starting with date_from until the next date
in the sequence would be after date_to.
Notes
The sequence can be in ascending or descending date order
based upon whether date_from is greater than date_to.
Returns
- A list of dates.
Examples
iex> d = ~D[2019-01-31]
~D[2019-01-31]
iex> d2 = ~D[2019-05-31]
~D[2019-05-31]
iex> Calendrical.interval(d, 3, :months)
[~D[2019-01-31], ~D[2019-02-28], ~D[2019-03-31]]
iex> Calendrical.interval(d, d2, :months)
[~D[2019-01-31], ~D[2019-02-28], ~D[2019-03-31],
~D[2019-04-30], ~D[2019-05-31]]
@spec interval_stream( date_from :: Date.t(), date_to_or_count :: Date.t() | non_neg_integer(), precision() ) :: fun()
Returns an a Stream function than can be lazily
enumerated.
This function has the same arguments and provides
the same functionality as interval/3 except that
it is lazily evaluated.
Arguments
date_fromis a anyCalendar.date/0that is the start of the sequence.date_to_or_countis upper bound of the sequence as aCalendar.date/0or the number of dates in the sequence to be generated.precisionis one of:years,:quarters,:months,:weeksor:days.
The sequence is generated starting with date_from until the next date
in the sequence would be after date_to.
Notes
The sequence can be in ascending or descending date order
based upon whether date_from is greater than date_to.
Returns
- A list of dates.
Examples
iex> d = ~D[2019-01-31]
~D[2019-01-31]
iex> d2 = ~D[2019-05-31]
~D[2019-05-31]
iex> Calendrical.interval_stream(d, 3, :months) |> Enum.to_list
[~D[2019-01-31], ~D[2019-02-28], ~D[2019-03-31]]
iex> Calendrical.interval_stream(d, d2, :months) |> Enum.to_list
[~D[2019-01-31], ~D[2019-02-28], ~D[2019-03-31],
~D[2019-04-30], ~D[2019-05-31]]
@spec iso_day_of_week(date()) :: Calendar.day_of_week()
Returns the ISO day of week for a date
where 1 means Monday and 7 means
Sunday.
Arguments
dateis anyCalendar.date/0or a map with one or more of the fields:year,:month,:dayand optionally:calendar.
Returns
- An integer ISO day of week in the range
1..7where1isMondayand7isSunday.
Examples
iex> {:ok, us_calendar} = Calendrical.calendar_from_locale("en")
iex> {:ok, us_date} = Date.new(2025, 1, 1, us_calendar)
iex> Calendrical.iso_day_of_week(us_date)
3
@spec iso_days_to_day_of_week(Calendar.iso_days() | Calendar.day()) :: day_of_week()
Returns the day of the week for a given
iso_day_number
Arguments
iso_day_numberis the number of days since the start of the epoch. SeeCalendrical.date_to_iso_days/1.
Returns
- An integer representing a day of the week where Monday
is represented by
1and Sunday is represented by7.
Examples
iex> days = Calendrical.date_to_iso_days(~D[2019-01-01])
iex> Calendrical.iso_days_to_day_of_week(days) == Calendrical.tuesday()
true
iex> days = Calendrical.date_to_iso_days(~D[2026-07-05])
iex> Calendrical.iso_days_to_day_of_week(days) == Calendrical.sunday()
true
@spec iso_week_of_year(date()) :: {Calendar.year(), week()} | date_error()
Returns the ISO week number for
a date.
Arguments
dateis anyCalendar.date/0or a map with one or more of the fields:year,:month,:dayand optionally:calendar.
Returns
a the ISO week of the year as an integer or
{:error, exception}for a date the calendar does not have.
Examples
iex> Calendrical.iso_week_of_year(~D[2019-01-01])
{2019, 1}
iex> Calendrical.iso_week_of_year(~D[2019-02-01])
{2019, 5}
iex> Calendrical.iso_week_of_year(~D[2019-W52-1 Calendrical.NRF])
{2020, 4}
iex> Calendrical.iso_week_of_year(~D[2019-W26-1 Calendrical.NRF])
{2019, 30}
iex> Calendrical.iso_week_of_year(~D[2019-12-01 Calendrical.Julian])
{2019, 50}
@spec last_day_of_year(date :: date()) :: Date.t() | {:error, Exception.t()}
Returns the last date of a year
for a Calendar.date/0.
Arguments
dateis anyCalendar.date/0.
Returns
a
Calendar.date/0or{:error, %Calendrical.InvalidDateError{}}for a date the calendar does not have.
Examples
iex> Calendrical.last_day_of_year(~D[2019-01-01])
~D[2019-12-31]
@spec last_day_of_year(year :: year(), calendar :: calendar()) :: Date.t() | {:error, Exception.t()}
Returns the last date of a year
for a calendar.
Arguments
yearis any year.calendaris any module that implements theCalendarandCalendricalbehaviours.
Returns
a
Calendar.date/0or{:error, %Calendrical.InvalidDateError{}}for a date the calendar does not have.
Examples
iex> Calendrical.last_day_of_year(2019, Calendrical.Gregorian)
%Date{calendar: Calendrical.Gregorian, day: 31, month: 12, year: 2019}
iex> Calendrical.last_day_of_year(2019, Calendrical.NRF)
%Date{calendar: Calendrical.NRF, day: 28, month: 12, year: 2019}
iex> Calendrical.last_day_of_year(5786, Calendrical.Hebrew)
~D[5786-12-29 Calendrical.Hebrew]
@spec last_gregorian_day_of_year(date()) :: Date.t() | {:error, Exception.t()}
Returns the gregorian date of the last day of a year
for a calendar.
Arguments
yearis any integer year number or adate/0.calendaris any module that implements theCalendarandCalendricalbehaviours orCalendar.ISO.
Returns
The
Date.t/0of the last day of the year: inCalendrical.Gregorianfor ayearandcalendar, and in the date's own calendar for a date.{:error, %Calendrical.InvalidDateError{}}if the calendar has no such year.
Examples
iex> Calendrical.last_gregorian_day_of_year(2019, Calendrical.Gregorian)
%Date{calendar: Calendrical.Gregorian, day: 31, month: 12, year: 2019}
iex> Calendrical.last_gregorian_day_of_year(2019, Calendrical.NRF)
%Date{calendar: Calendrical.Gregorian, day: 1, month: 2, year: 2020}
iex> Calendrical.last_gregorian_day_of_year(~D[2019-12-01])
~D[2019-12-31]
@spec last_gregorian_day_of_year(year(), calendar()) :: Date.t() | {:error, Exception.t()}
Returns the gregorian date of the last day of a year
for a calendar.
Arguments
yearis any integer year number.calendaris any module that implements theCalendarandCalendricalbehaviours orCalendar.ISO.
Returns
A
Date.t/0in theCalendrical.Gregoriancalendar or{:error, %Calendrical.InvalidDateError{}}.
Examples
iex> Calendrical.last_gregorian_day_of_year(2019, Calendrical.Gregorian)
%Date{calendar: Calendrical.Gregorian, day: 31, month: 12, year: 2019}
iex> Calendrical.last_gregorian_day_of_year(2019, Calendrical.NRF)
%Date{calendar: Calendrical.Gregorian, day: 1, month: 2, year: 2020}
iex> Calendrical.last_gregorian_day_of_year(5786, Calendrical.Hebrew)
~D[2026-09-11 Calendrical.Gregorian]
@spec localize(any_date_time()) :: {:ok, any_date_time()} | {:error, Exception.t()}
Localize a date by converting it to the calendar introspected from the current process locale.
Arguments
dateis anyCalendar.date/0.
Returns
{:ok, date}wheredateis converted into the calendar associated withLocalize.get_locale/0.{:error, exception}if the locale has no calendar.
Examples
iex> Localize.with_locale(:fr, fn -> Calendrical.localize(~D[2022-06-09]) end)
{:ok, %Date{year: 2022, month: 6, day: 9, calendar: Calendrical.FR}}
@spec localize(any_date_time(), Keyword.t() | atom()) :: {:ok, any_date_time()} | {:error, Exception.t()}
Localize a date by converting it to calendar introspected from the provided or default locale.
Arguments
dateis anyCalendar.date/0.optionsis aKeyword.t/0list of options. When it is instead an atom naming a date part, this function returnslocalize(date, part, []), seelocalize/3.
Options
:localeis a locale identifier atom, string, or aLocalize.LanguageTag.t/0. The default isLocalize.get_locale/0.
Returns
{:ok, date}wheredateis converted into the calendar associated with the current or provided locale.{:error, exception}if the locale is invalid or has no calendar.
Examples
iex> Calendrical.localize(~D[2022-06-09], locale: "fr")
{:ok, %Date{year: 2022, month: 6, day: 9, calendar: Calendrical.FR}}
@spec localize(any_date_time(), atom(), Keyword.t()) :: String.t() | {:error, Exception.t()}
@spec localize(datetime :: any_date_time(), part :: part(), options :: Keyword.t()) :: String.t() | {:error, Exception.t()}
Returns a localized string for a part of
a Calendar.date/0.
Arguments
dateis anyCalendar.date/0.partis one of:era,:quarter,:month,:day_of_weekor:days_of_week.optionsis aKeyword.t/0list of options.
Options
:localeis a locale identifier atom, string, or aLocalize.LanguageTag.t/0. The default isLocalize.get_locale/0.:styleis one of:wide,:abbreviatedor:narrow. The default is:abbreviated.:erawill, if set to:variantlocalize the era using the variant data. In the:enlocale, this will produceCEandBCErather than the defaultADandBC.:day_periodwill, if set to:variantlocalize the "AM"/"PM" time period indicator with the variant data. In the:enlocale, this will produceamandpmrather than the defaultAMandPM.
Returns
A string representing the localized date part, or
A list of strings representing the days of the week for when
partis:days_of_week. The days are in week order for the given date's calendar, or{:error, exception}for apart,:typeor:stylethat is not known, aCalendrical.InvalidPartError,Calendrical.InvalidTypeErrororCalendrical.InvalidStyleError, or for a date its calendar does not have, aCalendrical.InvalidDateError.
Examples
iex> Calendrical.localize(~D[2019-01-01], :era)
"AD"
iex> Calendrical.localize(~D[2019-01-01], :era, era: :variant)
"CE"
iex> Calendrical.localize(~D[2019-01-01], :day_of_week)
"Tue"
iex> Calendrical.localize(~D[0001-01-01], :day_of_week)
"Mon"
iex> Calendrical.localize(~D[2019-01-01], :days_of_week)
[{1, "Mon"}, {2, "Tue"}, {3, "Wed"}, {4, "Thu"}, {5, "Fri"}, {6, "Sat"}, {7, "Sun"}]
iex> Calendrical.localize(~D[2019-06-01], :era)
"AD"
iex> Calendrical.localize(~D[2019-06-01], :quarter)
"Q2"
iex> Calendrical.localize(~D[2019-06-01], :month)
"Jun"
iex> Calendrical.localize(~D[2019-06-01], :day_of_week)
"Sat"
iex> Calendrical.localize(~D[2019-06-01], :day_of_week, style: :wide)
"Saturday"
iex> Calendrical.localize(~D[2019-06-01], :day_of_week, style: :narrow)
"S"
iex> Calendrical.localize(~D[2019-06-01], :day_of_week, locale: "ar")
"السبت"
@spec min_days_for_locale(Localize.LanguageTag.t() | String.t() | atom()) :: 1..7 | {:error, Exception.t()}
Returns the minimum days in the first week of a year for a given locale.
Arguments
localeis any locale or locale name validated byLocalize.validate_locale/1.
Returns
The minimum number of days in the first week of the year for the territory associated with
localeor{:error, exception}whereexceptionis an exception struct.
Examples
iex> Calendrical.min_days_for_locale(:en)
1
iex> Calendrical.min_days_for_locale("en-GB")
4
@spec min_days_for_territory(atom() | String.t()) :: 1..7 | {:error, Exception.t()}
Returns the minimum days in the first week of a year for a given territory.
Arguments
territoryis any valid ISO3166-2 code.
Returns
The minimum number of days in the first week of the year for this territory or
{:error, exception}whereexceptionis an exception struct.
Examples
iex> Calendrical.min_days_for_territory(:US)
1
iex> Calendrical.min_days_for_territory(:GB)
4
@spec modified_julian_day(Date.t() | DateTime.t()) :: float()
Returns the Modified Julian Day of
a Calendar.date/0.
Arguments
date_or_datetimeis anyCalendar.date/0or aDateTime.t/0. If aDateTime.t/0is given, the result will be given in the current timezone.
Returns
- an number representing the
Modified Julian Day of the
date.
Notes
The Modified Julian Day is the number of days since November 17, 1858. Therefore this function only returns valid values for dates after this date.
Examples
iex> Calendrical.modified_julian_day(~D[2019-01-01])
58484.0
iex> Calendrical.modified_julian_day(~U[2019-01-01 12:00:00Z])
58484.5
iex> Calendrical.modified_julian_day(~U[2022-09-26 18:00:00.000Z])
59848.75
# If the given DateTime is not UTC, the result is given in
# the local timezone. This example requires a time zone database
# such as `tz` or `tzdata` to be configured.
#
# dt = DateTime.shift_zone!(~U[2019-01-01 14:00:00Z], "America/Sao_Paulo")
# #=> #DateTime<2019-01-01 12:00:00-02:00 -02 America/Sao_Paulo>
# Calendrical.modified_julian_day(dt)
# #=> 58484.5
@spec monday() :: 1
Returns the cardinal day number representing Monday.
Returns
1.
Examples
iex> Calendrical.monday()
1
@spec month_names(calendar :: calendar(), options :: Keyword.t()) :: [{pos_integer(), String.t()}] | {:error, Exception.t()}
Returns a sorted list of tuples containing ordinal months and month names for a give calendar.
Arguments
calendaris any calendar module.optionsis a keyword list of options.
Options
:localeis a locale identifier atom, string, or aLocalize.LanguageTag.t/0. The default isLocalize.get_locale/0.:typeis one of:stand_aloneor:format. The default is:format.:styleis one of:abbreviated,:wideor:narrow. The default is:abbreviated.
Returns
- A sorted list of tuples of the format
{ordinal month number, month name}.
Examples
iex> Calendrical.month_names(Calendar.ISO, style: :wide)
%{
1 => "January",
2 => "February",
3 => "March",
4 => "April",
5 => "May",
6 => "June",
7 => "July",
8 => "August",
9 => "September",
10 => "October",
11 => "November",
12 => "December"
}
iex> Calendrical.month_names(Calendar.ISO, locale: :de)
%{
1 => "Jan.",
2 => "Feb.",
3 => "März",
4 => "Apr.",
5 => "Mai",
6 => "Juni",
7 => "Juli",
8 => "Aug.",
9 => "Sept.",
10 => "Okt.",
11 => "Nov.",
12 => "Dez."
}
iex> Calendrical.month_names(Calendrical.Gregorian, locale: :fr, style: :narrow)
%{
1 => "J",
2 => "F",
3 => "M",
4 => "A",
5 => "M",
6 => "J",
7 => "J",
8 => "A",
9 => "S",
10 => "O",
11 => "N",
12 => "D"
}
@spec month_of_year(date()) :: Calendar.month() | {Calendar.month(), leap_month :: :leap} | date_error()
Returns the month number for
a date.
Arguments
dateis anyCalendar.date/0or a map with one or more of the fields:year,:month,:dayand optionally:calendar.
Returns
- The month of the year as an integer: the CLDR month the date's month is named by, which for a calendar of weeks is the Gregorian month its year begins in, counted on.
Examples
iex> Calendrical.month_of_year(~D[2019-01-01])
1
iex> Calendrical.month_of_year(~D[2019-12-01])
12The NRF year begins in February, so its twelfth month is named by January and its sixth, which holds week 26, by July:
iex> Calendrical.month_of_year(~D[2019-W52-1 Calendrical.NRF])
1
iex> Calendrical.month_of_year(~D[2019-W26-1 Calendrical.NRF])
7
@spec month_patterns(Localize.LanguageTag.t() | String.t() | atom(), atom()) :: {:ok, map() | nil} | {:error, Exception.t()}
Returns the month pattern data for a locale and calendar type.
Arguments
localeis a locale identifier atom, string, or aLocalize.LanguageTag.t/0. The default isLocalize.get_locale/0.calendaris a calendar type atom. The default is:gregorian.
Returns
{:ok, map}where the map holds the month pattern data.{:error, exception}if the calendar has no month patterns, as the Gregorian calendar has none.
Examples
iex> {:ok, patterns} = Calendrical.month_patterns(:en, :chinese)
iex> patterns.format.wide.leap
[0, "bis"]
iex> {:error, %Localize.ItemNotFoundError{}} = Calendrical.month_patterns(:en, :gregorian)
@spec months(Localize.LanguageTag.t() | String.t() | atom(), atom()) :: {:ok, map()} | {:error, Exception.t()}
Returns the month name data for a locale and calendar type.
Arguments
localeis a locale identifier atom, string, or aLocalize.LanguageTag.t/0. The default isLocalize.get_locale/0.calendaris a calendar type atom. The default is:gregorian.
Returns
{:ok, map}where the map holds the month name data.{:error, exception}if the locale has no month name data for the calendar.
Examples
iex> {:ok, months} = Calendrical.months(:en, :gregorian)
iex> months.format.wide[1]
"January"
@spec months_in_year(date()) :: Calendar.month() | {:error, Exception.t()}
Returns the number of months in the year of a date.
Delegates to Date.months_in_year/1. A calendar of weeks has the twelve months of its pattern of weeks; the weeks in its year are weeks_in_year/1.
Arguments
dateis anyCalendar.date/0.
Returns
The number of months in the year of
date, or{:error, exception}for a date with no year.
Examples
iex> Calendrical.months_in_year(~D[2026-07-05])
12
@spec named_month(Calendar.year(), Calendar.month(), calendar()) :: [Date.Range.t()]
Returns the days of a named month in a year, in the order of time.
A calendar that counts its months from the year's first day can
split the month that names them: Calendrical.Julian.March25 begins
its year on 25 March, so its March is two counted months, the year's
month 1 (25-31 March) and its month 13 (1-24 March), 364 days apart.
The named month's days are returned as one Date.Range.t/0 per
counted month that carries the name, earliest first.
Arguments
yearis any year incalendar.named_monthis the month that names the days: the monthcardinal_month/1answers, which is the month field itself in a calendar whose months are their own numbering.calendaris a module implementing theCalendricalbehaviour. The default isCalendrical.Gregorian.
Returns
- A list of one or two
Date.Range.t/0in time order, or[]when no month of the year carries the name.
Examples
iex> Calendrical.named_month(2026, 5)
[Date.range(~D[2026-05-01 Calendrical.Gregorian], ~D[2026-05-31 Calendrical.Gregorian])]
iex> Calendrical.named_month(1750, 3, Calendrical.Julian.March25)
[
Date.range(~D[1750-01-01 Calendrical.Julian.March25], ~D[1750-01-07 Calendrical.Julian.March25]),
Date.range(~D[1750-13-01 Calendrical.Julian.March25], ~D[1750-13-24 Calendrical.Julian.March25])
]
iex> Calendrical.named_month(2026, 14)
[]
@spec new(module(), calendar_type(), Keyword.t()) :: {:ok, calendar()} | {:error, Exception.t()}
Creates a new proleptic Gregorian calendar based upon the provided configuration.
If a module exists with the calendar_module name then it
is returned, not recreated.
Arguments
calendar_moduleis an atom representing the module name of the created calendar.calendar_typeis an atom of either:monthor:weekindicating which type of calendar is to be created.configis a Keyword list defining the configuration of the calendar.
Options
A :month calendar takes the options of Calendrical.Calendar.Shifted:
:baseis the calendar of months the year is cut from,Calendrical.Gregorianby default.:year_beginsis{month, day}of the base calendar the year begins on,{1, 1}by default.:year_numberis the base year the year takes its number from::beginning,:endingor:majority, the default.:written_yearis the year a date is written with,:baseby default, or:label.:weeksis the calendar's own week rule,[first_day: 1, min_days_in_first_week: 1]by default, or:from_first_day.:cldr_calendar_type,:era_calendar_type,:parsing_calendarand:years_in_cycleare facts forCalendrical.info/0.
A :week calendar takes the options of Calendrical.Calendar.Weeks:
:patternis the weeks in the three months of a quarter,[4, 5, 4]by default.:year_beginsis{weekday, :on_or_before, {month, day}}, or:year_endsis{weekday, :on_or_after, {month, day}}or{weekday, :nearest, {month, last_day}}; the default is{:monday, :on_or_before, {1, 1}}.:year_numberis the Gregorian year the year takes its number from,:majorityby default.:cldr_calendar_typeis the CLDR calendar that names the months,:gregorianby default.
Returns
{:ok, module}wheremoduleis the calendar module that conforms to theCalendarandCalendricalbehaviours. The call is idempotent: if the module already exists it is returned unchanged (it is not verified to be a calendar module in that case).{:error, exception}if the options are not valid, or aCalendrical.InvalidOptionValueErrorifcalendar_typeis neither:monthnor:week.
Examples
The ISO week calendar is a calendar of weeks whose year begins on the Monday on or before 4 January:
iex> {:ok, calendar} =
...> Calendrical.new(MyISOWeek, :week, year_begins: {:monday, :on_or_before, {1, 4}})
iex> calendar.date_from_iso_days(Date.to_gregorian_days(~D[2026-01-01]))
{2026, 1, 4}A fiscal year beginning in October, numbered by the year it ends in:
iex> {:ok, calendar} = Calendrical.new(Fiscal, :month, year_begins: {10, 1})
iex> calendar.date_from_iso_days(Date.to_gregorian_days(~D[2025-10-01]))
{2026, 1, 1}Note that Calendrical.ISOWeek is included as part of this
library.
@spec next( date() | Date.Range.t(), :year | :quarter | :month | :week | :day, Keyword.t() ) :: Date.t() | Date.Range.t() | {:error, Exception.t()}
Returns the next date or date range for a date period (year, quarter, month, week or day).
Arguments
date_or_date_rangeis anyCalendar.date/0orDate.Range.t/0.periodis:year,:quarter,:month,:weekor:day.optionsis a keyword list of options.
Options
- No options are currently defined. The argument is reserved and ignored.
Returns
When a Calendar.date/0 is passed, a Calendar.date/0 is
returned. When a Date.Range.t/0 is passed
a Date.Range.t/0 is returned.
Examples
iex> Calendrical.next(~D[2019-01-01], :day)
~D[2019-01-02]
iex> Calendrical.next(~D[2019-01-01], :month)
~D[2019-02-01]
iex> Calendrical.next(~D[2019-01-01], :quarter)
~D[2019-04-01]
iex> Calendrical.next(~D[2019-01-01], :year)
~D[2020-01-01]
@spec parse(String.t(), Keyword.t()) :: {:ok, Date.t() | Time.t() | NaiveDateTime.t() | DateTime.t() | Date.Range.t() | map() | {map(), map()}} | {:error, Exception.t()}
Parses a locale-formatted string as a date, time, datetime, or date range —
whichever matches. Delegates to Localize.DateTime.Parser.parse/2.
Useful when the input shape is not known up-front (e.g. a single
text field that may carry any of "2026-05-16",
"14:30", "May 16, 2026 2:30 PM", or
"May 5 – May 10, 2026"). The caller pattern-matches on the
returned struct to discover which kind of value was parsed.
Sub-parsers are tried in this order:
Interval (only when an interval-shaped separator is present) —
Calendrical.Date.parse_range/2.Date —
Calendrical.Date.parse/2.Time —
Calendrical.Time.parse/2.DateTime —
Calendrical.DateTime.parse/2.
The first sub-parser to return {:ok, _} wins; the order runs
from the most to the least structurally distinctive input shape.
Arguments
inputis the raw user input string.optionsis a keyword list of options.
Options
Forwarded to each sub-parser. Notable keys:
:locale— the locale to interpret the string under. Defaults toLocalize.get_locale/0.:calendar— the calendar module the input is read in and the result is returned in, such asCalendar.ISO(the default) orCalendrical.Hebrew. A CLDR calendar name such as:hebrewreturnsLocalize.UnknownCalendarError.:reference_date— the "today" anchor for two-digit-year pivoting and partial-date inheritance.:allow_inverted— applies to interval parsing only.:as—:struct(default) returns the appropriate struct (Date,Time,NaiveDateTime,DateTime, orDate.Range).:mapreturns a bare field map containing only what the input actually supplied — useful when a downstream library needs the unresolved partial rather than a struct with synthesised defaults. See the individualCalendrical.Date.parse/2,Calendrical.Time.parse/2, andCalendrical.DateTime.parse/2docs for the map shapes.
Returns
{:ok, value}wherevalueis one ofDate.t/0,Time.t/0,NaiveDateTime.t/0,DateTime.t/0, orDate.Range.t/0(struct mode), or a field map / a{from_map, to_map}tuple (map mode).{:error, Localize.DateTimeParseError.t()}when every sub-parser failed. The exception's:attemptsfield carries the{kind, exception}pairs from each attempt, in order.{:error, Localize.InvalidValueError.t()}wheninputis not a string or an option is malformed.{:error, %Calendrical.RemovedOptionError{}}for the:return_calendaroption, which was removed in 2.0.
Examples
iex> Calendrical.parse("2026-05-16", locale: :en)
{:ok, ~D[2026-05-16]}
iex> Calendrical.parse("14:30", locale: :en)
{:ok, ~T[14:30:00]}
iex> Calendrical.parse("2026-05-16T14:30:00", locale: :en)
{:ok, ~N[2026-05-16 14:30:00]}
iex> {:ok, range} = Calendrical.parse("2026-05-05 – 2026-05-10", locale: :en)
iex> {range.first, range.last}
{~D[2026-05-05], ~D[2026-05-10]}
iex> Calendrical.parse("May 5", locale: :en, as: :map)
{:ok, %{calendar: Calendar.ISO, month: 5, day: 5}}
iex> Calendrical.parse("11 am", locale: :en, as: :map)
{:ok, %{hour: 11}}
@spec previous( date() | Date.Range.t(), :year | :quarter | :month | :week | :day, Keyword.t() ) :: Date.t() | Date.Range.t() | {:error, Exception.t()}
Returns the previous date or date range for a date period (year, quarter, month, week or day).
Arguments
date_or_date_rangeis anyCalendar.date/0orDate.Range.t/0.periodis:year,:quarter,:month,:weekor:day.optionsis aKeyword.t/0list of options.
Options
- No options are currently defined. The argument is reserved and ignored.
Returns
When a Calendar.date/0 is passed, a Calendar.date/0 is
returned. When a Date.Range.t/0 is passed
a Date.Range.t/0 is returned.
Examples
iex> Calendrical.previous(~D[2019-01-01], :day)
~D[2018-12-31]
iex> Calendrical.previous(~D[2019-01-01], :quarter)
~D[2018-10-01]
iex> Calendrical.previous(~D[2019-01-01], :month)
~D[2018-12-01]
iex> Calendrical.previous(~D[2019-01-01], :year)
~D[2018-01-01]
@spec quarter_of_year(date()) :: quarter() | date_error()
Returns the quarter number for
a date.
Arguments
dateis anyCalendar.date/0or a map with one or more of the fields:year,:month,:dayand optionally:calendar.
Returns
- The quarter of the year as an integer.
Examples
iex> Calendrical.quarter_of_year(~D[2019-01-01])
1
iex> Calendrical.quarter_of_year(Calendrical.first_day_of_year(2019, Calendrical.NRF))
1
iex> Calendrical.quarter_of_year(Calendrical.last_day_of_year(2019, Calendrical.NRF))
4
@spec quarters(Localize.LanguageTag.t() | String.t() | atom(), atom()) :: {:ok, map()} | {:error, Exception.t()}
Returns the quarter name data for a locale and calendar type.
Arguments
localeis a locale identifier atom, string, or aLocalize.LanguageTag.t/0. The default isLocalize.get_locale/0.calendaris a calendar type atom. The default is:gregorian.
Returns
{:ok, map}where the map holds the quarter name data.{:error, exception}if the locale has no quarter name data for the calendar.
Examples
iex> {:ok, quarters} = Calendrical.quarters(:en, :gregorian)
iex> quarters.format.wide[1]
"1st quarter"
@spec saturday() :: 6
Returns the cardinal day number representing Saturday.
Returns
6.
Examples
iex> Calendrical.saturday()
6
@spec strftime(any_date_time(), String.t(), Keyword.t()) :: {:ok, String.t()} | {:error, Exception.t()}
Formats a date, time or datetime with Calendar.strftime/3, naming its
month, day of the week and day period in a locale.
The month and the day of the week are named from the date, as
Localize.Calendar.localize/3 names them, not from its fields: a
Hebrew month by its year, a Chinese leap month as a leap month, a
fiscal calendar's month by the month of the year it is, a calendar of
weeks' week by the month it falls in, and the day by the day it is,
whichever day the calendar's weeks begin on.
See Calendar.strftime/3 for the format string.
Arguments
valueis aDate.t/0,Time.t/0,NaiveDateTime.t/0orDateTime.t/0in any calendar.formatis aCalendar.strftime/3format string.optionsis a keyword list of options.
Options
:localeis a locale identifier atom, string, or aLocalize.LanguageTag.t/0. The default isLocalize.get_locale/0.Every option of
Calendar.strftime/3(:preferred_date,:preferred_time,:preferred_datetime,:month_namesand the other name callbacks). A name callback given here replaces the localized one.
Returns
{:ok, string}, or{:error, exception}if the locale is not valid, orvalue,formator an option cannot be formatted, or a name the format needs cannot be found forvalue.
Examples
iex> {:ok, israel} = Calendrical.calendar_for_territory(:IL)
iex> Calendrical.strftime(Date.convert!(~D[2025-01-26], israel), "%a", locale: :he)
{:ok, "יום א׳"}
iex> Calendrical.strftime(Date.new!(5779, 7, 1, Calendrical.Hebrew), "%A %B", locale: :en)
{:ok, "Friday Adar II"}
iex> Calendrical.strftime(~D[2019-11-03], "%x", locale: :fr, preferred_date: "%A %d %B %Y")
{:ok, "dimanche 03 novembre 2019"}
@spec strftime!(any_date_time(), String.t(), Keyword.t()) :: String.t()
Formats a date, time or datetime with Calendar.strftime/3, naming its
month, day of the week and day period in a locale, or raises.
Arguments
valueis aDate.t/0,Time.t/0,NaiveDateTime.t/0orDateTime.t/0in any calendar.formatis aCalendar.strftime/3format string.optionsis a keyword list of options.
Options
- The options of
strftime/3.
Returns
The formatted string, or
raises the exception
strftime/3returns.
Examples
iex> {:ok, israel} = Calendrical.calendar_for_territory(:IL)
iex> Calendrical.strftime!(Date.convert!(~D[2025-01-26], israel), "%A", locale: :en)
"Sunday"
Returns a keyword list of options than can be applied to
Calendar.strftime/3.
strftime_options! returns a keyword list than can be used as
options to return localised names for days, months and am/pm.
Calendar.strftime/3 passes the name callbacks the month field and
the calendar's own number for the day of the week, so these options
name them by those numbers. That is right for a calendar whose month
field is the CLDR month and whose weeks begin on Monday, and wrong
for the Hebrew and lunisolar calendars, fiscal and week calendars,
and calendars whose weeks begin on another day. strftime/3 names
the month and the day from the date and is right for every calendar.
Arguments
optionsis a keyword list of options. The default is[].
Options
:localeis a locale identifier atom, string, or aLocalize.LanguageTag.t/0. The default isLocalize.get_locale/0.:calendaris the name of any known calendar. The default isCalendrical.Gregorian.
Returns
- A keyword list of the functions
Calendar.strftime/3takes for:am_pm_names,:month_names,:abbreviated_month_names,:day_of_week_namesand:abbreviated_day_of_week_names.
Raises an exception if the locale or calendar is not known.
Examples
iex> options = Calendrical.strftime_options!(locale: "en")
iex> Keyword.keys(options)
[:am_pm_names, :month_names, :abbreviated_month_names, :day_of_week_names, :abbreviated_day_of_week_names]
iex> Calendar.strftime(~D[2025-01-26], "%a",
...> Calendrical.strftime_options!(locale: "en"))
"Sun"
@spec sunday() :: 7
Returns the cardinal day number representing Sunday.
Returns
7.
Examples
iex> Calendrical.sunday()
7
@spec supported_cldr_calendar_types() :: [atom(), ...]
Returns the list of CLDR calendar types supported by Calendrical.
The returned types are the names recognised by
Localize.validate_calendar/1 and are the valid
inputs to calendar_from_cldr_calendar_type/1.
Returns
- A list of CLDR calendar type atoms.
Examples
iex> calendars = Calendrical.supported_cldr_calendar_types()
iex> :gregorian in calendars and :persian in calendars and :hebrew in calendars
true
@spec thursday() :: 4
Returns the cardinal day number representing Thursday.
Returns
4.
Examples
iex> Calendrical.thursday()
4
@spec traditional_months(date()) :: [traditional_month()]
Returns a year's months in order, named traditionally, with any leap month among them.
For a lunisolar calendar the list is the year's traditional months
in the order the year holds them, with the leap month as
{month, :leap} after the month it follows. For every other
calendar the months are their own numbering, so the list is simply
1 up to the year's month count. The nth element of the list names
the year's nth ordinal month — the month a date of the calendar
carries.
Arguments
dateis anyCalendar.date/0or a map with one or more of the fields:year,:month,:dayand optionally:calendar.
Returns
- A list of
traditional_month/0in time order.
Examples
iex> Calendrical.traditional_months(Date.new!(4660, 1, 1, Calendrical.Chinese))
[1, 2, {2, :leap}, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
iex> Calendrical.traditional_months(~D[2026-01-01])
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
@spec traditional_months(Calendar.year(), calendar()) :: [traditional_month()]
Returns a year's months in order, named traditionally, with any leap month among them.
This is traditional_months/1 with the year and calendar supplied
directly; use this arity when the calendar is chosen at runtime.
Arguments
yearis any year incalendar.calendaris a module implementing theCalendricalbehaviour.
Returns
- A list of
traditional_month/0in time order.
Examples
# The Hebrew year 5784 is a leap year: Adar I follows the
# fifth traditional month
iex> Calendrical.traditional_months(5784, Calendrical.Hebrew)
[1, 2, 3, 4, 5, {5, :leap}, 6, 7, 8, 9, 10, 11, 12]
iex> Calendrical.traditional_months(5785, Calendrical.Hebrew)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
iex> Calendrical.traditional_months(2026, Calendrical.Gregorian)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
@spec tuesday() :: 2
Returns the cardinal day number representing Tuesday.
Returns
2.
Examples
iex> Calendrical.tuesday()
2
@spec validate_calendar(term()) :: {:ok, calendar()} | {:error, Exception.t()}
Validates if the argument is a Calendrical calendar module.
A calendar is a module that implements Elixir's Calendar behaviour
and the Calendrical behaviour (see calendar_module?/1). If the
calendar is Calendar.ISO, which implements Calendar alone, then
the validated calendar is returned as Calendrical.Gregorian.
Arguments
calendar_moduleis a module that implements theCalendarandCalendricalbehaviours.
Returns
{:ok, calendar_module}or{:error, exception}whereexceptionis an exception struct.
Examples
iex> Calendrical.validate_calendar(Calendrical.Gregorian)
{:ok, Calendrical.Gregorian}
iex> Calendrical.validate_calendar(Calendar.ISO)
{:ok, Calendrical.Gregorian}
iex> {:error, %Calendrical.InvalidCalendarModuleError{module: :not_a_calendar}} =
...> Calendrical.validate_calendar(:not_a_calendar)
@spec wednesday() :: 3
Returns the cardinal day number representing Wednesday.
Returns
3.
Examples
iex> Calendrical.wednesday()
3
@spec week_of_month(date()) :: {Calendar.month(), week()} | date_error()
Returns the {month, week_number} for a date: the month the date's week belongs to and the week's number in it.
The weeks are the calendar's own, so a day near the end of a month can be in the next month's first week. Calendar.ISO dates are counted in Calendrical.Gregorian, whose weeks begin on Monday and whose week 1 of a month is the week holding the month's first day, so Monday 31 December 2018 is in week 1 of January 2019. Calendrical.ISO keeps ISO 8601's rule, under which a week belongs to the month holding four or more of its days.
Arguments
dateis anyCalendar.date/0or a map with one or more of the fields:year,:month,:dayand optionally:calendar.
Returns
a tuple of the form
{month, week}, or{:error, exception}if the date is missing a field.
Examples
iex> Calendrical.week_of_month(~D[2019-01-01])
{1, 1}
iex> Calendrical.week_of_month(~D[2018-12-31])
{1, 1}
iex> Calendrical.week_of_month(~D[2021-10-01 Calendrical.ISO])
{9, 5}
iex> {:ok, weeks_from_first_day} = Calendrical.new(MyApp.WeeksFromFirstDay, :month, weeks: :from_first_day)
iex> Calendrical.week_of_month(Date.convert!(~D[2019-01-01], weeks_from_first_day))
{1, 1}
iex> Calendrical.week_of_month(Date.convert!(~D[2018-12-31], weeks_from_first_day))
{12, 5}
iex> Calendrical.week_of_month(~D[2018-12-31 Calendrical.Julian])
{12, 5}
@spec week_of_year(date()) :: {Calendar.year(), week()} | date_error()
Returns the {year, week_number}
for a date.
Arguments
dateis anyCalendar.date/0or a map with one or more of the fields:year,:month,:dayand optionally:calendar.
Returns
a the week of the year as an integer or
{:error, exception}for a date the calendar does not have.
Examples
iex> Calendrical.week_of_year(~D[2019-01-01])
{2019, 1}
iex> Calendrical.week_of_year(~D[2019-12-01])
{2019, 48}
iex> Calendrical.week_of_year(~D[2019-W52-1 Calendrical.NRF])
{2019, 52}
iex> Calendrical.week_of_year(~D[2019-W26-1 Calendrical.NRF])
{2019, 26}
iex> Calendrical.week_of_year(~D[2019-12-01 Calendrical.Julian])
{2019, 48}
@spec weekday?(date(), Keyword.t()) :: boolean() | {:error, Exception.t()}
Returns whether a given date is a weekday.
Weekdays are locale-specific and depend on the policies of a given territory (region, country).
Arguments
dateis anyCalendar.date/0.optionsis aKeyword.t/0list of options.
Options
:localeis any locale or locale name validated byLocalize.validate_locale/1. The default isLocalize.get_locale/0which returns the locale set for the current process.:territoryis any valid ISO-3166-2 territory that is validated byLocalize.validate_territory/1.
Notes
When identifying which territory context within which to determine whether a given day is a weekday or not the following order applies:
A territory specified by the
:territoryoption.The territory defined as part of the
:localeoption.The territory defined as part of the current processes default locale.
Returns
trueif the date is a weekday day in the territory, otherwisefalse.{:error, exception}if the locale or territory is not known.
Examples
# The default locale is `en-001` for which
# the territory is `001` (the world). The weekdays
# for `001` are Monday to Friday
iex> Calendrical.weekday?(~D[2019-03-23], locale: :en)
false
iex> Calendrical.weekday?(~D[2019-03-23], territory: "IS")
false
# Saturday is a weekday in India
iex> Calendrical.weekday?(~D[2019-03-23], locale: :"en-IN")
true
# Friday is not a weekday in Saudi Arabia
iex> Calendrical.weekday?(~D[2019-03-22], locale: :"ar-SA")
false
# Friday is not a weekday in Israel
iex> Calendrical.weekday?(~D[2019-03-22], locale: :he)
false
iex> {:ok, israel} = Calendrical.calendar_for_territory(:IL)
iex> Calendrical.weekday?(Date.convert!(~D[2019-03-22], israel), locale: :he)
false
@spec weekdays(atom() | String.t()) :: [day_of_week()] | {:error, Exception.t()}
Returns a list of the days of the week that are considered a weekend for a given territory (country).
Arguments
territoryis any valid ISO3166-2 code.
Returns
- A list of integers representing the days of
the week that are week days. Here
1meansMondayand7meansSunday.
Notes
The list of days may not be monotonic. See the example for Saudi Arabia below.
Examples
iex> Calendrical.weekdays("US")
[1, 2, 3, 4, 5]
iex> Calendrical.weekdays("IN")
[1, 2, 3, 4, 5, 6]
iex> Calendrical.weekdays("SA")
[1, 2, 3, 4, 7]
iex> {:error, %Localize.UnknownTerritoryError{}} = Calendrical.weekdays("yy")
@spec weekend(atom() | String.t()) :: [day_of_week()] | {:error, Exception.t()}
Returns a list of the days of the week that are considered a weekend for a given territory (region, country).
Arguments
territoryis any valid ISO3166-2 code.
Returns
- A list of integers representing the days of
the week that are weekend days. Here
1meansMondayand7meansSunday.
Examples
iex> Calendrical.weekend("US")
[6, 7]
iex> Calendrical.weekend("IN")
[7]
iex> Calendrical.weekend("SA")
[5, 6]
iex> {:error, %Localize.UnknownTerritoryError{}} = Calendrical.weekend("yy")
@spec weekend?(date(), Keyword.t()) :: boolean() | {:error, Exception.t()}
Returns whether a given date is a weekend day.
Weekend days are locale-specific and depend on the policies of a given territory (country).
Arguments
dateis anyCalendar.date/0.optionsis aKeyword.t/0list of options.
Options
:localeis any locale or locale name validated byLocalize.validate_locale/1. The default isLocalize.get_locale/0which returns the locale set for the current process.:territoryis any valid ISO-3166-2 territory that is validated byLocalize.validate_territory/1.
Notes
When identifying which territory context within which to determine whether a given day is a weekend or not the following order applies:
A territory specified by the
:territoryoption.The territory defined as part of the
:localeoption.The territory defined as part of the current processes default locale.
Returns
trueif the date is a weekend day in the territory, otherwisefalse.{:error, exception}if the locale or territory is not known.
Examples
# The default locale is `en-001` for which
# the territory is `001` (the world). The weekend
# for `001` is Saturday and Sunday
iex> Calendrical.weekend? ~D[2019-03-23]
true
iex> Calendrical.weekend?(~D[2019-03-23], locale: :en)
true
iex> Calendrical.weekend?(~D[2019-03-23], territory: "IS")
true
# In India the official weekend is only Sunday
iex> Calendrical.weekend?(~D[2019-03-23], locale: "en-IN")
false
# In Israel the weekend starts on Friday
iex> Calendrical.weekend?(~D[2019-03-22], locale: :he)
true
iex> {:ok, israel} = Calendrical.calendar_for_territory(:IL)
iex> Calendrical.weekend?(Date.convert!(~D[2019-03-22], israel), locale: :he)
true
# As it also does in Saudia Arabia
iex> Calendrical.weekend?(~D[2019-03-22], locale: :"ar-SA")
true
# Sunday is not a weekend day in Saudi Arabia
iex> Calendrical.weekend?(~D[2019-03-24], locale: :"ar-SA")
false
@spec weeks_in_year(date()) :: pos_integer() | {:error, Exception.t()}
Returns the number of weeks in a year.
Arguments
dateis anyCalendar.date/0or an integer year or a map with one or more of the fields:year,:month,:dayand optionally:calendar.
Returns
The number of weeks in the year, as
Calendrical.Week.weeks_in_year/2counts them: whole weeks, week 1 holding at least the fewest days of the year the calendar'sinfo/0states, or{:error, exception}for a year the calendar does not have.
Examples
# A Calendar.ISO date is handled by the default
# Calendrical.Gregorian calendar: Monday-start weeks
# with a one-day minimum first week (not ISO 8601 week
# numbering — use Calendrical.ISO for that). The number
# of weeks in a year is either 52 or 53 with each week
# being 7 days. The first week may start in the Gregorian
# year prior and end in the following Gregorian year.
iex> Calendrical.weeks_in_year(~D[2022-01-01])
52
iex> Calendrical.weeks_in_year(~D[2023-01-01])
53
# For week calculations, the Calendrical.ISO and Calendrical.ISOWeek
# have the same definition.
iex> Calendrical.weeks_in_year(2023, Calendrical.ISO)
52
iex> Calendrical.weeks_in_year(2020, Calendrical.ISOWeek)
53
iex> Calendrical.weeks_in_year(~D[2026-W01-1 Calendrical.ISOWeek])
53
# A calendar whose weeks start on the first day of the year
# has a short last week, its 53rd.
iex> {:ok, weeks_from_first_day} = Calendrical.new(MyApp.WeeksFromFirstDay, :month, weeks: :from_first_day)
iex> weeks_from_first_day.weeks_in_year(2023)
53
iex> weeks_from_first_day.weeks_in_year(2020)
53
@spec weeks_in_year(year(), calendar()) :: pos_integer() | date_error()
Returns the number of weeks in a year for
a calendar.
Arguments
yearis any integer year number.calendaris any module that implements theCalendarandCalendricalbehaviours orCalendar.ISO.Calendar.ISOis treated as the defaultCalendrical.Gregoriancalendar — Monday-start weeks with a one-day minimum first week — the same convention applied toCalendar.ISOdates throughout Calendrical, not ISO 8601 week numbering. For ISO 8601 weeks (four-day minimum first week) useCalendrical.ISOorCalendrical.ISOWeek.
Returns
The number of weeks in the year, or
{:error, %Calendrical.InvalidDateError{}}for a year the calendar does not have, or{:error, %Calendrical.MissingFieldsError{}}whenyearisnil.
Examples
iex> Calendrical.weeks_in_year(2023, Calendar.ISO)
53
# ISO 8601 week numbering gives 52 weeks for 2023.
iex> Calendrical.weeks_in_year(2023, Calendrical.ISO)
52
iex> Calendrical.weeks_in_year(2020, Calendrical.ISOWeek)
53
Returns the number of whole days in n weeks.
A fractional number of weeks is truncated toward zero to whole days: one and a half weeks is 10 days.
Arguments
nis a number of weeks, an integer or a float.
Returns
- The number of whole days in
nweeks, as an integer.
Examples
iex> Calendrical.weeks_to_days(2)
14
iex> Calendrical.weeks_to_days(1.5)
10
@spec year_of_era(date()) :: {Calendar.day(), Calendar.era()} | date_error()
Returns the {year_of_era, era} for
a date.
This function differs slightly
from Date.year_of_era/1. See the notes
below
Arguments
dateis anyCalendar.date/0or a map with one or more of the fields:year,:month,:dayand optionally:calendar.
Returns
- a the year since the start of the era and the era of the year as a tuple.
Notes
Unlike
Date.year_of_era/1, this function supports eras that change part way through the calendar year. This is common in the Japanese calendar where the eras change when a new emperor is ordained which can happen at any time of year. Therefore this function is consistent withDate.year_of_era/1for the Gregorian and related calendars, but returns a different (and more accurate) result for the Japanese calendar.This is also true for fiscal year calendars that start on a day other than January 1st. The year of era will depend on whether the calendar was configured with
year: :beginning,year: :endingoryear: :majority.
Examples
iex> Calendrical.year_of_era(~D[2019-01-01])
{2019, 1}
iex> Calendrical.year_of_era(Calendrical.first_day_of_year(2019, Calendrical.NRF))
{2019, 1}
iex> Calendrical.year_of_era(Calendrical.last_day_of_year(2019, Calendrical.NRF))
{2019, 1}