Elixir v1.6.0 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 the year, month, day, etc. designations 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

A calendar implementation

Any map/struct that contains the date fields

Any map/struct that contains the datetime fields

The internal time format is used when converting between calendars

The internal date format that is used when converting between calendars

Microseconds with stored precision

Any map/struct that contains the naive_datetime fields

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

Any map/struct that contains the time fields

The time zone ID according to the IANA tz database (e.g. Europe/Zurich)

The time zone UTC offset in seconds

The time zone abbreviation (e.g. CET or CEST or BST etc.)

Functions

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

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

Callbacks

Converts the date into a string according to the calendar

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

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

Define the rollover moment for the given calendar

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

Returns true if the given year is a leap year

Converts t:iso_days to the Calendar’s datetime format

Converts the given datetime (with time zone) into the t:iso_days format

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

Converts t:day_fraction to the Calendar’s time format

Converts the given time to the t:day_fraction format

Converts the time into a string according to the calendar

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

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

Link to this section Types

Link to this type calendar() View Source
calendar() :: module()

A calendar implementation

Link to this type date() View Source
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
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_fraction() View Source
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 iso_days() View Source
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.00000 in ISO 8601 notation (also known as midnight 1 January BC 1 of the proleptic Gregorian calendar).

The parts_per_day represent how many subparts the current day is subdivided in (for different calendars, picking a different parts_per_day might make sense). The parts_in_day represents how many of these parts_per_day have passed in the last day.

Link to this type microsecond() View Source
microsecond() :: {0..999_999, 0..6}

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 naive_datetime() View Source
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 std_offset() View Source
std_offset() :: integer()

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

Link to this type time() View Source
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
time_zone() :: String.t()

The time zone ID according to the IANA tz database (e.g. Europe/Zurich)

Link to this type utc_offset() View Source
utc_offset() :: integer()

The time zone UTC offset in seconds

Link to this type zone_abbr() View Source
zone_abbr() :: String.t()

The time zone abbreviation (e.g. CET or CEST or BST etc.)

Link to this section Functions

Link to this function compatible_calendars?(calendar, calendar) View Source
compatible_calendars?(Calendar.calendar(), 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 truncate(microsecond_tuple, atom) View Source
truncate(Calendar.microsecond(), :microsecond | :millisecond | :second) ::
  Calendar.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
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
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_week(year, month, day) View Source
day_of_week(year(), month(), day()) :: non_neg_integer()

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

Link to this callback day_rollover_relative_to_midnight_utc() View Source
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
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
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 naive_datetime_from_iso_days(iso_days) View Source
naive_datetime_from_iso_days(iso_days()) ::
  {year(), month(), day(), hour(), minute(), second(), microsecond()}

Converts t:iso_days to the Calendar’s datetime format.

Link to this callback naive_datetime_to_iso_days(year, month, day, hour, minute, second, microsecond) View Source
naive_datetime_to_iso_days(
  year(),
  month(),
  day(),
  hour(),
  minute(),
  second(),
  microsecond()
) :: iso_days()

Converts the given datetime (with time zone) into the t:iso_days format.

Link to this callback naive_datetime_to_string(year, month, day, hour, minute, second, microsecond) View Source
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 time_from_day_fraction(day_fraction) View Source
time_from_day_fraction(day_fraction()) ::
  {hour(), minute(), second(), microsecond()}

Converts t:day_fraction to the Calendar’s time format.

Link to this callback time_to_day_fraction(hour, minute, second, microsecond) View Source
time_to_day_fraction(hour(), minute(), second(), microsecond()) ::
  day_fraction()

Converts the given time to the t:day_fraction format.

Link to this callback time_to_string(hour, minute, second, microsecond) View Source
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
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
valid_time?(hour(), minute(), second(), microsecond()) :: boolean()

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