# Elixir v1.10.3 Calendar behaviour View Source

This module defines the responsibilities for working with calendars, dates, times and datetimes in Elixir.

Currently it defines types and the minimal implementation for a calendar behaviour in Elixir. The goal of the Calendar features in Elixir is to provide a base for interoperability instead of full-featured datetime API.

For the actual date, time and datetime structures, see `Date`, `Time`, `NaiveDateTime` and `DateTime`.

Note designations for year, month, day, and the like, are overspecified (i.e. an integer instead of `1..12` for months) because different calendars may have a different number of days per month, months per year and so on.

# Link to this section Summary

## Types

calendar()

A calendar implementation

date()

Any map/struct that contains the date fields

datetime()

Any map/struct that contains the datetime fields

day()
day_fraction()

The internal time format is used when converting between calendars.

day_of_era()

A tuple representing the `day` and the `era`.

day_of_week()
era()
hour()
iso_days()

The internal date format that is used when converting between calendars.

microsecond()

Microseconds with stored precision.

minute()
month()
naive_datetime()

Any map/struct that contains the naive_datetime fields

second()
std_offset()

The time zone standard offset in seconds (not zero in summer times)

time()

Any map/struct that contains the time fields

time_zone()

The time zone ID according to the IANA tz database (for example, Europe/Zurich)

time_zone_database()

Specifies the time zone database for calendar operations.

utc_offset()

The time zone UTC offset in seconds

week()
year()
zone_abbr()

The time zone abbreviation (for example, CET or CEST or BST, and such)

## Functions

compatible_calendars?(calendar, calendar)

Returns `true` if two calendars have the same moment of starting a new day, `false` otherwise.

get_time_zone_database()

Gets the current time zone database.

put_time_zone_database(database)

Sets the current time zone database.

truncate(microsecond_tuple, atom)

Returns a microsecond tuple truncated to a given precision (`:microsecond`, `:millisecond` or `:second`).

## Callbacks

date_to_string(year, month, day)

Converts the date into a string according to the calendar.

datetime_to_string(year, month, day, hour, minute, second, microsecond, time_zone, zone_abbr, utc_offset, std_offset)

Converts the datetime (with time zone) into a string according to the calendar.

day_of_era(year, month, day)

Calculates the day and era from the given `year`, `month`, and `day`.

day_of_week(year, month, day)

Calculates the day of the week from the given `year`, `month`, and `day`.

day_of_year(year, month, day)

Calculates the day of the year from the given `year`, `month`, and `day`.

day_rollover_relative_to_midnight_utc()

Define the rollover moment for the given calendar.

days_in_month(year, month)

Returns how many days there are in the given year-month.

leap_year?(year)

Returns `true` if the given year is a leap year.

months_in_year(year)

Returns how many months there are in the given year.

naive_datetime_from_iso_days(iso_days)

Converts `t:iso_days/0` to the Calendar's datetime format.

naive_datetime_to_iso_days(year, month, day, hour, minute, second, microsecond)

Converts the given datetime (without time zone) into the `t:iso_days/0` format.

naive_datetime_to_string(year, month, day, hour, minute, second, microsecond)

Converts the datetime (without time zone) into a string according to the calendar.

parse_date(arg1)

Parses the string representation for a date returned by `c:date_to_string/3` into a date-tuple.

parse_naive_datetime(arg1)

Parses the string representation for a naive datetime returned by `c:naive_datetime_to_string/7` into a naive-datetime-tuple.

parse_time(arg1)

Parses the string representation for a time returned by `c:time_to_string/4` into a time-tuple.

parse_utc_datetime(arg1)

Parses the string representation for a datetime returned by `c:datetime_to_string/11` into a datetime-tuple.

quarter_of_year(year, month, day)

Calculates the quarter of the year from the given `year`, `month`, and `day`.

time_from_day_fraction(day_fraction)

Converts `t:day_fraction/0` to the Calendar's time format.

time_to_day_fraction(hour, minute, second, microsecond)

Converts the given time to the `t:day_fraction/0` format.

time_to_string(hour, minute, second, microsecond)

Converts the time into a string according to the calendar.

valid_date?(year, month, day)

Should return `true` if the given date describes a proper date in the calendar.

valid_time?(hour, minute, second, microsecond)

Should return `true` if the given time describes a proper time in the calendar.

year_of_era(year)

Calculates the year and era from the given `year`.

# Link to this section Types

Link to this type

# calendar()

View Source

## Specs

    calendar() :: module()

A calendar implementation

Link to this type

# date()

View Source

## Specs

    date() :: %{
      optional(any()) => any(),
      :calendar => calendar(),
      :year => year(),
      :month => month(),
      :day => day()
    }

Any map/struct that contains the date fields

Link to this type

# datetime()

View Source

## Specs

    datetime() :: %{
      optional(any()) => any(),
      :calendar => calendar(),
      :year => year(),
      :month => month(),
      :day => day(),
      :hour => hour(),
      :minute => minute(),
      :second => second(),
      :microsecond => microsecond(),
      :time_zone => time_zone(),
      :zone_abbr => zone_abbr(),
      :utc_offset => utc_offset(),
      :std_offset => std_offset()
    }

Any map/struct that contains the datetime fields

Link to this type

# day()

View Source

## Specs

    day() :: pos_integer()

Link to this type

# day_fraction()

View Source

## Specs

    day_fraction() ::
      {parts_in_day :: non_neg_integer(), parts_per_day :: pos_integer()}

The internal time format is used when converting between calendars.

It represents time as a fraction of a day (starting from midnight). `parts_in_day` specifies how much of the day is already passed, while `parts_per_day` signifies how many parts there fit in a day.

Link to this type

# day_of_era()

View Source

## Specs

    day_of_era() :: {day :: non_neg_integer(), era()}

A tuple representing the `day` and the `era`.

Link to this type

# day_of_week()

View Source

## Specs

    day_of_week() :: non_neg_integer()

Link to this type

# era()

View Source

## Specs

    era() :: non_neg_integer()

Link to this type

# hour()

View Source

## Specs

    hour() :: non_neg_integer()

Link to this type

# iso_days()

View Source

## Specs

    iso_days() :: {days :: integer(), day_fraction()}

The internal date format that is used when converting between calendars.

This is the number of days including the fractional part that has passed of the last day since 0000-01-01+00:00T00:00.000000 in ISO 8601 notation (also known as midnight 1 January BC 1 of the proleptic Gregorian calendar).

Link to this type

# microsecond()

View Source

## Specs

    microsecond() :: {non_neg_integer(), non_neg_integer()}

Microseconds with stored precision.

The precision represents the number of digits that must be used when representing the microseconds to external format. If the precision is 0, it means microseconds must be skipped.

Link to this type

# minute()

View Source

## Specs

    minute() :: non_neg_integer()

Link to this type

# month()

View Source

## Specs

    month() :: pos_integer()

Link to this type

# naive_datetime()

View Source

## Specs

    naive_datetime() :: %{
      optional(any()) => any(),
      :calendar => calendar(),
      :year => year(),
      :month => month(),
      :day => day(),
      :hour => hour(),
      :minute => minute(),
      :second => second(),
      :microsecond => microsecond()
    }

Any map/struct that contains the naive_datetime fields

Link to this type

# second()

View Source

## Specs

    second() :: non_neg_integer()

Link to this type

# std_offset()

View Source

## Specs

    std_offset() :: integer()

The time zone standard offset in seconds (not zero in summer times)

Link to this type

# time()

View Source

## Specs

    time() :: %{
      optional(any()) => any(),
      :hour => hour(),
      :minute => minute(),
      :second => second(),
      :microsecond => microsecond()
    }

Any map/struct that contains the time fields

Link to this type

# time_zone()

View Source

## Specs

    time_zone() :: String.t()

The time zone ID according to the IANA tz database (for example, Europe/Zurich)

Link to this type

# time_zone_database()

View Source

## Specs

    time_zone_database() :: module()

Specifies the time zone database for calendar operations.

Many functions in the `DateTime` module require a time zone database. By default, it uses the default time zone database returned by `Calendar.get_time_zone_database/0`, which defaults to `Calendar.UTCOnlyTimeZoneDatabase` which only handles "Etc/UTC" datetimes and returns `{:error, :utc_only_time_zone_database}` for any other time zone.

Other time zone databases (including ones provided by packages) can be configured as default either via configuration:

    config :elixir, :time_zone_database, CustomTimeZoneDatabase

or by calling `Calendar.put_time_zone_database/1`.

See `Calendar.TimeZoneDatabase` for more information on custom time zone databases.

Link to this type

# utc_offset()

View Source

## Specs

    utc_offset() :: integer()

The time zone UTC offset in seconds

Link to this type

# week()

View Source

## Specs

    week() :: pos_integer()

Link to this type

# year()

View Source

## Specs

    year() :: integer()

Link to this type

# zone_abbr()

View Source

## Specs

    zone_abbr() :: String.t()

The time zone abbreviation (for example, CET or CEST or BST, and such)

# Link to this section Functions

Link to this function

# compatible_calendars?(calendar, calendar)

View Source (since 1.5.0)

## Specs

    compatible_calendars?(calendar(), calendar()) :: boolean()

Returns `true` if two calendars have the same moment of starting a new day, `false` otherwise.

If two calendars are not compatible, we can only convert datetimes and times between them. If they are compatible, this means that we can also convert dates as well as naive datetimes between them.

Link to this function

# get_time_zone_database()

View Source (since 1.8.0)

## Specs

    get_time_zone_database() :: time_zone_database()

Gets the current time zone database.

Link to this function

# put_time_zone_database(database)

View Source (since 1.8.0)

## Specs

    put_time_zone_database(time_zone_database()) :: :ok

Sets the current time zone database.

Link to this function

# truncate(microsecond_tuple, atom)

View Source (since 1.6.0)

## Specs

    truncate(microsecond(), :microsecond | :millisecond | :second) :: microsecond()

Returns a microsecond tuple truncated to a given precision (`:microsecond`, `:millisecond` or `:second`).

# Link to this section Callbacks

Link to this callback

# date_to_string(year, month, day)

View Source

## Specs

    date_to_string(year(), month(), day()) :: String.t()

Converts the date into a string according to the calendar.

Link to this callback

# datetime_to_string(year, month, day, hour, minute, second, microsecond, time_zone, zone_abbr, utc_offset, std_offset)

View Source

## Specs

    datetime_to_string(
      year(),
      month(),
      day(),
      hour(),
      minute(),
      second(),
      microsecond(),
      time_zone(),
      zone_abbr(),
      utc_offset(),
      std_offset()
    ) :: String.t()

Converts the datetime (with time zone) into a string according to the calendar.

Link to this callback

# day_of_era(year, month, day)

View Source

## Specs

    day_of_era(year(), month(), day()) :: day_of_era()

Calculates the day and era from the given `year`, `month`, and `day`.

Link to this callback

# day_of_week(year, month, day)

View Source

## Specs

    day_of_week(year(), month(), day()) :: day_of_week()

Calculates the day of the week from the given `year`, `month`, and `day`.

Link to this callback

# day_of_year(year, month, day)

View Source

## Specs

    day_of_year(year(), month(), day()) :: non_neg_integer()

Calculates the day of the year from the given `year`, `month`, and `day`.

Link to this callback

# day_rollover_relative_to_midnight_utc()

View Source

## Specs

    day_rollover_relative_to_midnight_utc() :: day_fraction()

Define the rollover moment for the given calendar.

This is the moment, in your calendar, when the current day ends and the next day starts.

The result of this function is used to check if two calendars rollover at the same time of day. If they do not, we can only convert datetimes and times between them. If they do, this means that we can also convert dates as well as naive datetimes between them.

This day fraction should be in its most simplified form possible, to make comparisons fast.

## Examples

- If, in your Calendar, a new day starts at midnight, return {0, 1}.
- If, in your Calendar, a new day starts at sunrise, return {1, 4}.
- If, in your Calendar, a new day starts at noon, return {1, 2}.
- If, in your Calendar, a new day starts at sunset, return {3, 4}.

Link to this callback

# days_in_month(year, month)

View Source

## Specs

    days_in_month(year(), month()) :: day()

Returns how many days there are in the given year-month.

Link to this callback

# leap_year?(year)

View Source

## Specs

    leap_year?(year()) :: boolean()

Returns `true` if the given year is a leap year.

A leap year is a year of a longer length than normal. The exact meaning is up to the calendar. A calendar must return `false` if it does not support the concept of leap years.

Link to this callback

# months_in_year(year)

View Source

## Specs

    months_in_year(year()) :: month()

Returns how many months there are in the given year.

Link to this callback

# naive_datetime_from_iso_days(iso_days)

View Source

## Specs

    naive_datetime_from_iso_days(iso_days()) ::
      {year(), month(), day(), hour(), minute(), second(), microsecond()}

Converts `t:iso_days/0` to the Calendar's datetime format.

Link to this callback

# naive_datetime_to_iso_days(year, month, day, hour, minute, second, microsecond)

View Source

## Specs

    naive_datetime_to_iso_days(
      year(),
      month(),
      day(),
      hour(),
      minute(),
      second(),
      microsecond()
    ) :: iso_days()

Converts the given datetime (without time zone) into the `t:iso_days/0` format.

Link to this callback

# naive_datetime_to_string(year, month, day, hour, minute, second, microsecond)

View Source

## Specs

    naive_datetime_to_string(
      year(),
      month(),
      day(),
      hour(),
      minute(),
      second(),
      microsecond()
    ) :: String.t()

Converts the datetime (without time zone) into a string according to the calendar.

Link to this callback

# parse_date(arg1)

View Source (since 1.10.0)

## Specs

    parse_date(String.t()) :: {:ok, {year(), month(), day()}} | {:error, atom()}

Parses the string representation for a date returned by `c:date_to_string/3` into a date-tuple.

Link to this callback

# parse_naive_datetime(arg1)

View Source (since 1.10.0)

## Specs

    parse_naive_datetime(String.t()) ::
      {:ok, {year(), month(), day(), hour(), minute(), second(), microsecond()}}
      | {:error, atom()}

Parses the string representation for a naive datetime returned by `c:naive_datetime_to_string/7` into a naive-datetime-tuple.

The given string may contain a timezone offset but it is ignored.

Link to this callback

# parse_time(arg1)

View Source (since 1.10.0)

## Specs

    parse_time(String.t()) ::
      {:ok, {hour(), minute(), second(), microsecond()}} | {:error, atom()}

Parses the string representation for a time returned by `c:time_to_string/4` into a time-tuple.

Link to this callback

# parse_utc_datetime(arg1)

View Source (since 1.10.0)

## Specs

    parse_utc_datetime(String.t()) ::
      {:ok, {year(), month(), day(), hour(), minute(), second(), microsecond()},
       utc_offset()}
      | {:error, atom()}

Parses the string representation for a datetime returned by `c:datetime_to_string/11` into a datetime-tuple.

The returned datetime must be in UTC. The original `utc_offset` it was written in must be returned in the result.

Link to this callback

# quarter_of_year(year, month, day)

View Source

## Specs

    quarter_of_year(year(), month(), day()) :: non_neg_integer()

Calculates the quarter of the year from the given `year`, `month`, and `day`.

Link to this callback

# time_from_day_fraction(day_fraction)

View Source

## Specs

    time_from_day_fraction(day_fraction()) ::
      {hour(), minute(), second(), microsecond()}

Converts `t:day_fraction/0` to the Calendar's time format.

Link to this callback

# time_to_day_fraction(hour, minute, second, microsecond)

View Source

## Specs

    time_to_day_fraction(hour(), minute(), second(), microsecond()) ::
      day_fraction()

Converts the given time to the `t:day_fraction/0` format.

Link to this callback

# time_to_string(hour, minute, second, microsecond)

View Source

## Specs

    time_to_string(hour(), minute(), second(), microsecond()) :: String.t()

Converts the time into a string according to the calendar.

Link to this callback

# valid_date?(year, month, day)

View Source

## Specs

    valid_date?(year(), month(), day()) :: boolean()

Should return `true` if the given date describes a proper date in the calendar.

Link to this callback

# valid_time?(hour, minute, second, microsecond)

View Source

## Specs

    valid_time?(hour(), minute(), second(), microsecond()) :: boolean()

Should return `true` if the given time describes a proper time in the calendar.

Link to this callback

# year_of_era(year)

View Source

## Specs

    year_of_era(year()) :: {year(), era()}

Calculates the year and era from the given `year`.