Calendrical.Interval (Calendrical v2.2.0)

Copy Markdown

Constructs and compares date intervals for any Calendrical calendar.

An interval is represented as an Elixir Date.Range.t/0 whose :first and :last dates are in the desired calendar. Ranges produced by this module are enumerable and have the day as their unit of precision.

The constructor functions cover the standard calendrical units: year/2, quarter/3, month/3, week/3, and day/3. Each one also accepts a single Calendar.date/0 argument and returns the interval that contains that date.

compare/2 and the corresponding relation/2 (re-exported from Calendrical.IntervalRelation) implement Allen's interval algebra, returning one of 13 atoms describing how two ranges relate.

Summary

Functions

Compares two date ranges and returns the Allen-algebra relation between them.

Returns a Date.Range.t/0 that represents the day containing date.

Returns a Date.Range.t/0 that represents the month containing date.

Returns a Date.Range.t/0 that represents the quadrimester (third of the year).

Returns a Date.Range.t/0 that represents the quarter containing date.

Returns a Date.Range.t/0 that represents the semester (half of the year).

Returns a Date.Range.t/0 that represents the week containing date.

Returns a Date.Range.t/0 that represents the year containing date.

Functions

compare(r1, r2)

@spec compare(range_1 :: Date.Range.t(), range_2 :: Date.Range.t()) ::
  Calendrical.interval_relation()

Compares two date ranges and returns the Allen-algebra relation between them.

Uses Allen's Interval Algebra to return one of 13 different relationships:

RelationConverse
:precedes:preceded_by
:meets:met_by
:overlaps:overlapped_by
:finished_by:finishes
:contains:during
:starts:started_by
:equals:equals

Arguments

Returns

  • An atom representing the relationship of range_1 to range_2.

Examples

iex> Calendrical.Interval.compare Calendrical.Interval.day(~D[2019-01-01]),
...> Calendrical.Interval.day(~D[2019-01-02])
:meets

iex> Calendrical.Interval.compare Calendrical.Interval.day(~D[2019-01-01]),
...> Calendrical.Interval.day(~D[2019-01-03])
:precedes

iex> Calendrical.Interval.compare Calendrical.Interval.day(~D[2019-01-03]),
...> Calendrical.Interval.day(~D[2019-01-01])
:preceded_by

iex> Calendrical.Interval.compare Calendrical.Interval.day(~D[2019-01-02]),
...> Calendrical.Interval.day(~D[2019-01-01])
:met_by

iex> Calendrical.Interval.compare Calendrical.Interval.day(~D[2019-01-02]),
...> Calendrical.Interval.day(~D[2019-01-02])
:equals

day(date)

Returns a Date.Range.t/0 that represents the day containing date.

The range is enumerable.

Arguments

Returns

  • A Date.Range.t/0 representing the enumerable days in the day containing date, in date's calendar, or

  • {:error, %Calendrical.InvalidDateError{}} for a date the calendar does not have, or

  • {:error, %Calendrical.MissingFieldsError{}} for a date missing a field.

Examples

iex> Calendrical.Interval.day(~D[2019-06-15])
Date.range(~D[2019-06-15], ~D[2019-06-15])

day(year, day, calendar \\ Calendrical.Gregorian)

Returns a Date.Range.t/0 containing a single day.

The range is enumerable.

Arguments

Returns

  • A Date.Range.t/0 containing the single requested day, or

  • {:error, %Calendrical.InvalidDateError{}} if day is greater than the number of days in the year.

Examples

iex> {:ok, _} =
...>   Calendrical.new(MyApp.FiscalUS, :month,
...>     year_begins: {10, 1},
...>     year_number: :majority,
...>     weeks: [first_day: 7, min_days_in_first_week: 4]
...>   )
iex> Calendrical.Interval.day 2019, 52, MyApp.FiscalUS
Date.range(Date.new!(2019, 2, 21, MyApp.FiscalUS), Date.new!(2019, 2, 21, MyApp.FiscalUS))

iex> Calendrical.Interval.day 2019, 92, Calendrical.NRF
Date.range(~D[2019-W14-1 Calendrical.NRF], ~D[2019-W14-1 Calendrical.NRF])

iex> Calendrical.Interval.day 2019, 8, Calendrical.ISOWeek
Date.range(~D[2019-W02-1 Calendrical.ISOWeek], ~D[2019-W02-1 Calendrical.ISOWeek])

month(date)

@spec month(Date.t()) :: Date.Range.t() | Calendrical.date_error()

Returns a Date.Range.t/0 that represents the month containing date.

The range is enumerable.

Arguments

Returns

  • A Date.Range.t/0 representing the enumerable days in the month containing date, in date's calendar.

  • {:error, %Calendrical.InvalidDateError{}} for a date the calendar does not have, or

  • {:error, %Calendrical.MissingFieldsError{}} for a date missing a field.

Examples

iex> Calendrical.Interval.month(~D[2019-06-15])
Date.range(~D[2019-06-01], ~D[2019-06-30])

month(year, month, calendar \\ Calendrical.Gregorian)

Returns a Date.Range.t/0 that represents the month.

The range is enumerable.

Arguments

Returns

Examples

iex> {:ok, _} = Calendrical.new(MyApp.FiscalUK, :month, year_begins: {4, 1}, year_number: :majority)
iex> Calendrical.Interval.month 2019, 3, MyApp.FiscalUK
Date.range(Date.new!(2019, 3, 1, MyApp.FiscalUK), Date.new!(2019, 3, 30, MyApp.FiscalUK))

iex> {:ok, _} =
...>   Calendrical.new(MyApp.FiscalUS, :month,
...>     year_begins: {10, 1},
...>     year_number: :majority,
...>     weeks: [first_day: 7, min_days_in_first_week: 4]
...>   )
iex> Calendrical.Interval.month 2019, 3, MyApp.FiscalUS
Date.range(Date.new!(2019, 3, 1, MyApp.FiscalUS), Date.new!(2019, 3, 31, MyApp.FiscalUS))

quadrimester(year, quadrimester, calendar \\ Calendrical.Gregorian)

Returns a Date.Range.t/0 that represents the quadrimester (third of the year).

The range is enumerable.

Arguments

Returns

  • A Date.Range.t/0 representing the enumerable days in the quadrimester, or

  • {:error, exception} for a quadrimester the year does not have.

Examples

iex> Calendrical.Interval.quadrimester 2026, 2
Date.range(~D[2026-05-01 Calendrical.Gregorian], ~D[2026-08-31 Calendrical.Gregorian])

quarter(date)

@spec quarter(Date.t()) :: Date.Range.t() | Calendrical.date_error()

Returns a Date.Range.t/0 that represents the quarter containing date.

The range is enumerable.

Arguments

Returns

  • A Date.Range.t/0 representing the enumerable days in the quarter containing date, in date's calendar.

  • {:error, exception} for a date the calendar does not have.

Examples

iex> Calendrical.Interval.quarter(~D[2019-06-15])
Date.range(~D[2019-04-01], ~D[2019-06-30])

quarter(year, quarter, calendar \\ Calendrical.Gregorian)

Returns a Date.Range.t/0 that represents the quarter.

The range is enumerable.

Arguments

Returns

Examples

iex> {:ok, _} = Calendrical.new(MyApp.FiscalUK, :month, year_begins: {4, 1}, year_number: :majority)
iex> Calendrical.Interval.quarter 2019, 2, MyApp.FiscalUK
Date.range(Date.new!(2019, 4, 1, MyApp.FiscalUK), Date.new!(2019, 6, 30, MyApp.FiscalUK))

iex> Calendrical.Interval.quarter 2019, 2, Calendrical.ISOWeek
Date.range(~D[2019-W14-1 Calendrical.ISOWeek], ~D[2019-W26-7 Calendrical.ISOWeek])

semester(year, semester, calendar \\ Calendrical.Gregorian)

Returns a Date.Range.t/0 that represents the semester (half of the year).

The range is enumerable.

Arguments

Returns

  • A Date.Range.t/0 representing the enumerable days in the semester, or

  • {:error, exception} for a semester the year does not have.

Examples

iex> Calendrical.Interval.semester 2026, 2
Date.range(~D[2026-07-01 Calendrical.Gregorian], ~D[2026-12-31 Calendrical.Gregorian])

week(date)

@spec week(Date.t()) :: Date.Range.t() | Calendrical.date_error()

Returns a Date.Range.t/0 that represents the week containing date.

The range is enumerable.

Arguments

Returns

  • A Date.Range.t/0 representing the enumerable days in the week containing date, in date's calendar.

  • {:error, exception} for a date the calendar does not have.

Examples

iex> Calendrical.Interval.week(~D[2019-06-15])
Date.range(~D[2019-06-10], ~D[2019-06-16])

week(year, week, calendar \\ Calendrical.Gregorian)

Returns a Date.Range.t/0 that represents the week.

The range is enumerable.

Arguments

Returns

  • A Date.Range.t/0 representing the enumerable days in the week, or

  • {:error, exception} for a week the year does not have.

Examples

iex> {:ok, _} =
...>   Calendrical.new(MyApp.FiscalUS, :month,
...>     year_begins: {10, 1},
...>     year_number: :majority,
...>     weeks: [first_day: 7, min_days_in_first_week: 4]
...>   )
iex> Calendrical.Interval.week 2019, 52, MyApp.FiscalUS
Date.range(Date.new!(2019, 12, 22, MyApp.FiscalUS), Date.new!(2019, 12, 28, MyApp.FiscalUS))

iex> Calendrical.Interval.week 2019, 52, Calendrical.NRF
Date.range(~D[2019-W52-1 Calendrical.NRF], ~D[2019-W52-7 Calendrical.NRF])

iex> Calendrical.Interval.week 2019, 52, Calendrical.ISOWeek
Date.range(~D[2019-W52-1 Calendrical.ISOWeek], ~D[2019-W52-7 Calendrical.ISOWeek])

iex> Calendrical.Interval.week 2019, 52, Calendrical.Julian
Date.range(~D[2019-12-24 Calendrical.Julian], ~D[2019-12-30 Calendrical.Julian])

year(date)

@spec year(Date.t()) :: Date.Range.t() | Calendrical.date_error()

Returns a Date.Range.t/0 that represents the year containing date.

The range is enumerable.

Arguments

Returns

  • A Date.Range.t/0 representing the enumerable days in the year containing date, in date's calendar, or

  • {:error, %Calendrical.InvalidDateError{}} for a date the calendar does not have, or

  • {:error, %Calendrical.MissingFieldsError{}} for a date with no year.

Examples

iex> Calendrical.Interval.year(~D[2019-06-15])
Date.range(~D[2019-01-01], ~D[2019-12-31])

year(year, calendar \\ Calendrical.Gregorian)

Returns a Date.Range.t/0 that represents the year.

The range is enumerable.

Arguments

Returns

Examples

iex> {:ok, _} = Calendrical.new(MyApp.FiscalUK, :month, year_begins: {4, 1}, year_number: :majority)
iex> Calendrical.Interval.year 2019, MyApp.FiscalUK
Date.range(Date.new!(2019, 1, 1, MyApp.FiscalUK), Date.new!(2019, 12, 31, MyApp.FiscalUK))

iex> Calendrical.Interval.year 2019, Calendrical.NRF
Date.range(~D[2019-W01-1 Calendrical.NRF], ~D[2019-W52-7 Calendrical.NRF])