Timex.Comparable protocol (timex v4.0.0)

Copy Markdown View Source

This protocol is used for comparing and diffing different date/time representations

Built-in date implementations assume Calendar.ISO fields with years from 0 through 9999. Use the public Timex.compare/3 and Timex.diff/3 entrypoints for input validation. Calendar differences also require UTC instants within this range, independent of the local wall year.

Summary

Types

t()

All the types that implement this protocol.

Functions

Compare two date or datetime types.

Get the difference between two date or datetime types.

Types

comparable()

@type comparable() ::
  Date.t()
  | DateTime.t()
  | NaiveDateTime.t()
  | Timex.Types.date()
  | Timex.Types.datetime()

compare_result()

@type compare_result() :: -1 | 0 | 1 | {:error, term()}

constants()

@type constants() :: :epoch | :zero | :distant_past | :distant_future

diff_result()

@type diff_result() :: Timex.Duration.t() | integer() | {:error, term()}

granularity()

@type granularity() ::
  :year
  | :years
  | :month
  | :months
  | :week
  | :weeks
  | :calendar_week
  | :calendar_weeks
  | :day
  | :days
  | :hour
  | :hours
  | :minute
  | :minutes
  | :second
  | :seconds
  | :millisecond
  | :milliseconds
  | :microsecond
  | :microseconds
  | :duration

t()

@type t() :: term()

All the types that implement this protocol.

Functions

compare(a, b, granularity)

@spec compare(comparable(), comparable(), granularity()) :: compare_result()

Compare two date or datetime types.

Specify a comparison granularity from the following:

  • :year
  • :years
  • :month
  • :months
  • :week
  • :weeks
  • :calendar_week (weeks of the calendar as opposed to actual weeks in terms of days)
  • :calendar_weeks
  • :day
  • :days
  • :hour
  • :hours
  • :minute
  • :minutes
  • :second
  • :seconds
  • :millisecond
  • :milliseconds
  • :microsecond
  • :microseconds
  • :duration

and the dates will be compared with the corresponding accuracy. The protocol requires an explicit granularity. Timex.compare/2 and Timex.diff/2 default to :microsecond.

  • 0: when equal
  • -1: when the first date/time comes before the second
  • 1: when the first date/time comes after the second
  • {:error, reason}: when there was a problem comparing, perhaps due to a value being passed which is not a valid date/datetime

Examples

iex> use Timex
iex> date1 = ~D[2014-03-04]
iex> date2 = ~D[2015-03-04]
iex> Timex.compare(date1, date2, :year)
-1
iex> Timex.compare(date2, date1, :year)
1
iex> Timex.compare(date1, date1)
0

diff(a, b, granularity)

@spec diff(comparable(), comparable(), granularity()) :: diff_result()

Get the difference between two date or datetime types.

Specify a diff granularity from the following:

  • :year
  • :years
  • :month
  • :months
  • :week
  • :weeks
  • :calendar_week (weeks of the calendar as opposed to actual weeks in terms of days)
  • :calendar_weeks
  • :day
  • :days
  • :hour
  • :hours
  • :minute
  • :minutes
  • :second
  • :seconds
  • :millisecond
  • :milliseconds
  • :microsecond
  • :microseconds
  • :duration

and the result will be an integer value of those units or a Duration struct. The diff value will be negative if a comes before b, and positive if a comes after b. This behaviour mirrors compare/3.

When using granularity of :months, the number of days in the month varies. This behavior mirrors Timex.shift/2.

Examples

iex> use Timex
iex> date1 = ~D[2015-01-28]
iex> date2 = ~D[2015-02-28]
iex> Timex.diff(date1, date2, :month)
-1
iex> Timex.diff(date2, date1, :month)
1

iex> use Timex
iex> date1 = ~D[2015-01-31]
iex> date2 = ~D[2015-02-28]
iex> Timex.diff(date1, date2, :month)
-1
iex> Timex.diff(date2, date1, :month)
0