View Source Tempus.Guards (Tempus v0.16.0)

Handy guards to simplify pattern matching slots

Summary

Functions

Guard to compare two instances of Tempus.Slot.origin/0.

For any calendar, checks if the former argument comes before the latter one.

is_covered(o, s) deprecated

Due to compiler limitations, this macro is gone for v1.18+, use is_slot_covered/2 and/or is_datetime_covered/2 explicitly.

Syntactic sugar for is_struct(term, Date).

Syntactic sugar for is_struct(term, DateTime).

Guard to validate if two DateTime instances passed as parameters if the former one is less (comes earlier) than the latter one.

Guard to validate if the DateTime instance passed as a first argument is covered by the slot.

Guard to validate if two DateTime instances passed as parameters for pointing to the same DateTime. If arguments have different timezones, returns a meaningful value for positive unix epoch only.

For any calendar, checks if the former argument comes before the latter one.

Guard to validate one slot ovelaps another

Returns true if the year is leap, and false otherwise.

Guard to validate that the term given is actually a Tempus.Slot.origin/0 or a function which might be used as a slot locator.

Guard to validate that the term given is actually a Tempus.Slot.origin/0

Syntactic sugar for is_struct(term, Tempus.Slot).

Guard to validate whether the DateTime.t/0 given as the first argument is the border of the slot.

Guard to validate if two Tempus.Slot instances passed as parameters if the former one is less (comes earlier) than the latter one.

Guard to validate if the slot instance passed as a first argument is covered by the slot passed last.

Guard to validate whether two slots are equal

Guard to validate whether the slot is nil (has neither end set.)

Guard to validate whether the slot is open (has either end not set)

Syntactic sugar for is_struct(term, Time).

Helper to validate one slot overlaps another in delta. Unlike guards, this function does not expect arguments in the correct order, and would return true if the slots overlap even if s2 comes before s1.

Macro to convert the DateTime struct to epoch. Unlike DateTime.to_unix/2, it does not support different Calendars but Calendar.ISO, and it does not support negative epoch times.

Functions

is_coming_before(o1, o2)

(since 0.9.0) (macro)
@spec is_coming_before(
  Date.t() | DateTime.t() | Tempus.Slot.t(),
  Date.t() | DateTime.t() | Tempus.Slot.t()
) :: boolean()

Guard to compare two instances of Tempus.Slot.origin/0.

Beware this guards returns a meaningful true/false if and only all the input types are correct. When passing not t:Slot.origin/0 as any of parameter it would return false and therefore it’s negation is tricky.

Examples

iex> import Tempus.Guards, only: [is_coming_before: 2]
...> is_coming_before(~D[2023-04-10], ~U[2023-04-11T00:00:00.000000Z])
true
iex> is_coming_before(~D[2023-04-10], ~D[2023-04-10])
false
iex> s_bcn = ~U[2023-06-26T09:30:00Z]
...> s_ny = ~D|2024-06-26| |> Tempus.Slot.wrap() |> Tempus.Slot.shift_tz("America/New_York")
...> is_coming_before(s_bcn, s_ny)
true

is_coming_before_in_ms(dt1, dt2)

(since 0.9.0) (macro)
@spec is_coming_before_in_ms(DateTime.t(), DateTime.t()) :: boolean()

For any calendar, checks if the former argument comes before the latter one.

Allowed in guard tests. Inlined by the compiler.

is_covered(o, s)

(since 0.9.0) (macro)
This macro is deprecated. use `is_slot_covered/2` and/or `is_datetime_covered/2` instead.
@spec is_covered(Tempus.Slot.t() | DateTime.t(), Tempus.Slot.t()) :: false

Due to compiler limitations, this macro is gone for v1.18+, use is_slot_covered/2 and/or is_datetime_covered/2 explicitly.

This guard will always return false for v1.18 and will be removed in v1.19

is_date(term)

(since 0.9.0) (macro)

Syntactic sugar for is_struct(term, Date).

is_datetime(term)

(since 0.9.0) (macro)

Syntactic sugar for is_struct(term, DateTime).

is_datetime_coming_before(dt1, dt2)

(since 0.9.0) (macro)

Guard to validate if two DateTime instances passed as parameters if the former one is less (comes earlier) than the latter one.

If arguments have different timezones, returns a meaningful value for positive unix epoch only.

If arguments are not datetimes, or timezones differ and values are before epoch, returns false.

Examples

iex> import Tempus.Guards, only: [is_datetime_coming_before: 2]
...> is_datetime_coming_before(~U|2020-01-01T12:00:00Z|,
...>     DateTime.shift_zone!(~U|2020-01-01T12:00:00Z|, "Australia/Sydney"))
false
iex> is_datetime_coming_before(~U|2000-01-01T12:00:00Z|, ~U|2000-01-01T23:59:59Z|)
true

is_datetime_covered(dt, s)

(since 0.9.0) (macro)

Guard to validate if the DateTime instance passed as a first argument is covered by the slot.

Examples

iex> import Tempus.Guards, only: [is_datetime_covered: 2]
...> slot = Tempus.slot!(~U|2020-01-01T12:00:00Z|, ~U|2020-01-01T23:59:59Z|)
...> is_datetime_covered(~U|2020-01-01T18:00:00Z|, slot)
true
...> is_datetime_covered(~U|2020-01-01T06:00:00Z|, slot)
false

is_datetime_equal(dt1, dt2)

(since 0.9.0) (macro)

Guard to validate if two DateTime instances passed as parameters for pointing to the same DateTime. If arguments have different timezones, returns a meaningful value for positive unix epoch only.

Examples

iex> import Tempus.Guards, only: [is_datetime_equal: 2]
...> is_datetime_equal(~U|2020-01-01T12:00:00Z|,
...>     DateTime.shift_zone!(~U|2020-01-01T12:00:00Z|, "Australia/Sydney"))
true
iex> is_datetime_equal(~U|2000-01-01T12:00:00Z|, ~U|2000-01-01T23:59:59Z|)
false

is_equal_in_ms(dt1, dt2)

(since 0.9.0) (macro)
@spec is_equal_in_ms(DateTime.t(), DateTime.t()) :: boolean()

For any calendar, checks if the former argument comes before the latter one.

Allowed in guard tests. Inlined by the compiler.

is_joint(s1, s2)

(since 0.9.0) (macro)
@spec is_joint(Tempus.Slot.t(), Tempus.Slot.t()) :: boolean()

Guard to validate one slot ovelaps another

Examples

iex> import Tempus.Guards, only: [is_joint: 2]
...> import Tempus.Sigils
...> s1 = ~I[2023-04-09 23:00:00Z|2023-04-10 00:59:59Z]
...> s2 = Tempus.Slot.wrap(~D|2023-04-10|)
...> is_joint(s1, s2)
true
iex> s1 = ~I[2023-04-09 23:00:00Z|2023-04-10 00:00:00Z]
...> s2 = Tempus.Slot.wrap(~D|2023-04-10|)
...> is_joint(s1, s2)
true

is_leap(year)

(since 0.9.0) (macro)

Returns true if the year is leap, and false otherwise.

Examples

iex> import Tempus.Guards, only: [is_leap: 1]
...> is_leap(1970)
false
...> is_leap(2000)
true

Allowed in guard tests. Inlined by the compiler.

is_locator(origin)

(since 0.9.0) (macro)
@spec is_locator(Tempus.Slot.origin() | (Tempus.Slot.t() -> boolean()) | any()) ::
  boolean()

Guard to validate that the term given is actually a Tempus.Slot.origin/0 or a function which might be used as a slot locator.

Examples

iex> import Tempus.Guards, only: [is_locator: 1, is_coming_before: 2]
...> is_locator(Date.utc_today())
true
...> is_locator(& Date.utc_today() |> Tempus.Slot.wrap() |> is_coming_before(&1))
true
...> is_locator(true)
false

is_origin(term)

(since 0.9.0) (macro)
@spec is_origin(Tempus.Slot.origin() | any()) :: boolean()

Guard to validate that the term given is actually a Tempus.Slot.origin/0

Examples

iex> import Tempus.Guards, only: [is_origin: 1]
...> is_origin(Date.utc_today())
true
...> is_origin(nil)
true
...> is_origin(:ok)
false

is_slot(term)

(since 0.9.0) (macro)

Syntactic sugar for is_struct(term, Tempus.Slot).

is_slot_border(dt, s)

(since 0.9.0) (macro)
@spec is_slot_border(DateTime.t(), Tempus.Slot.t()) :: boolean()

Guard to validate whether the DateTime.t/0 given as the first argument is the border of the slot.

Examples

iex> import Tempus.Guards, only: [is_slot_border: 2]
iex> dt = DateTime.utc_now()
...> is_slot_border(dt, %Tempus.Slot{from: dt, to: nil})
true
iex> is_slot_border(dt, Tempus.Slot.wrap(Date.utc_today()))
false

is_slot_coming_before(s1, s2)

(since 0.9.0) (macro)

Guard to validate if two Tempus.Slot instances passed as parameters if the former one is less (comes earlier) than the latter one.

If arguments have different timezones, returns a meaningful value for positive unix epoch only.

If arguments are not slots, or timezones differ and values are before epoch, returns false.

Examples

iex> import Tempus.Guards, only: [is_slot_coming_before: 2]
...> slot = Tempus.Slot.wrap(~U|2020-01-01T12:00:00Z|)
...> is_slot_coming_before(slot, Tempus.Slot.shift_tz(slot, "Australia/Sydney"))
false
...> is_slot_coming_before(slot, Tempus.Slot.wrap(~U|2020-01-01T23:59:59Z|))
true

is_slot_covered(s1, s2)

(since 0.9.0) (macro)

Guard to validate if the slot instance passed as a first argument is covered by the slot passed last.

Examples

iex> import Tempus.Guards, only: [is_slot_covered: 2]
...> slot = Tempus.slot!(~U|2020-01-01T12:00:00Z|, ~U|2020-01-01T23:59:59Z|)
...> covering = Tempus.Slot.wrap(~D|2020-01-01|)
...> joint = Tempus.slot!(~U|2020-01-01T06:00:00Z|, ~U|2020-01-01T18:00:00Z|)
...> is_slot_covered(slot, covering)
true
iex> is_slot_covered(slot, joint)
false

is_slot_equal(s1, s2)

(since 0.9.0) (macro)
@spec is_slot_equal(Tempus.Slot.t(), Tempus.Slot.t()) :: boolean()

Guard to validate whether two slots are equal

Examples

iex> import Tempus.Guards, only: [is_slot_equal: 2]
...> import Tempus.Sigils
...> s1 = ~I[2023-04-09 00:00:00Z|2023-04-09 23:59:59.999999Z]
...> s2 = Tempus.Slot.wrap(~D|2023-04-09|)
...> s3 = ~I[2023-04-09 00:00:00Z|2023-04-09 23:59:59Z]
...> is_slot_equal(s1, s1)
true
iex> is_slot_equal(s1, s2)
true
iex> is_slot_equal(s1, s3)
false
iex> s_bcn = ~U[2023-06-26T09:30:00Z]
...> {:ok, s_ny} = DateTime.shift_zone(s_bcn, "America/New_York")
...> is_slot_equal(Tempus.Slot.wrap(s_bcn), Tempus.Slot.wrap(s_ny))
true

is_slot_nil(s)

(since 0.9.0) (macro)
@spec is_slot_nil(Tempus.Slot.t()) :: boolean()

Guard to validate whether the slot is nil (has neither end set.)

Examples

iex> import Tempus.Guards, only: [is_slot_nil: 1]
iex> is_slot_nil(Tempus.Slot.id())
true
iex> is_slot_nil(Tempus.Slot.wrap(Date.utc_today()))
false
iex> is_slot_nil(:ok)
false

is_slot_open(s)

(since 0.9.0) (macro)
@spec is_slot_open(Tempus.Slot.t()) :: boolean()

Guard to validate whether the slot is open (has either end not set)

Please note, that the slot having both ends set to nil is considered a special case and is not reported as open.

Examples

iex> import Tempus.Guards, only: [is_slot_open: 1]
iex> is_slot_open(%Tempus.Slot{from: nil, to: DateTime.utc_now()})
true
iex> is_slot_open(Tempus.Slot.wrap(Date.utc_today()))
false
iex> is_slot_open(:ok)
false

is_time(term)

(since 0.9.0) (macro)

Syntactic sugar for is_struct(term, Time).

joint_in_delta?(s1, s2, delta)

(since 0.9.0)
@spec joint_in_delta?(
  Tempus.Slot.t(),
  Tempus.Slot.t(),
  non_neg_integer() | [{System.time_unit(), non_neg_integer()}]
) :: boolean()

Helper to validate one slot overlaps another in delta. Unlike guards, this function does not expect arguments in the correct order, and would return true if the slots overlap even if s2 comes before s1.

Examples

iex> import Tempus.Guards, only: [joint_in_delta?: 3]
...> import Tempus.Sigils
...> s1 = ~I[2023-04-09 23:00:00Z|2023-04-09 23:59:59Z]
...> joint_in_delta?(s1, s1, 1)
true
iex> s2 = Tempus.Slot.wrap(~D|2023-04-10|)
...> joint_in_delta?(s1, s2, 1)
true
iex> joint_in_delta?(s2, s1, 1)
true
iex> joint_in_delta?(s1, s2, microsecond: 500)
false

to_unix(data, unit \\ :microsecond)

(since 0.9.0) (macro)

Macro to convert the DateTime struct to epoch. Unlike DateTime.to_unix/2, it does not support different Calendars but Calendar.ISO, and it does not support negative epoch times.

It although supports timezones and can be used in guards.

Examples

iex> import Tempus.Guards, only: [to_unix: 2]
...> dt = DateTime.utc_now()
...> to_unix(dt, :second) == DateTime.to_unix(dt, :second)
true
...> to_unix(dt, :millisecond) == DateTime.to_unix(dt, :millisecond)
true
...> to_unix(dt, :microsecond) == DateTime.to_unix(dt, :microsecond)
true
...> to_unix(~U[2024-01-16 14:50:59.787204Z], :microsecond)
1705416659787204

Allowed in guard tests. Inlined by the compiler.