# `Ecto.DateTimeRange.Time`
[🔗](https://github.com/synchronal/ecto_date_time_range/blob/main/lib/ecto/date_time_range/time.ex#L1)

An `Ecto.Type` wrapping a `:tsrange` Postgres column. To the application, it appears as
a struct with `:start_at` and `:end_at`, with `t:Time.t()` values.

This type does not do any time zone conversions--times going in will be times coming out.

```
defmodule Core.Thing do
  use Ecto.Schema
  import Ecto.Changeset

  schema "things" do
    field :performed_during, Ecto.DateTimeRange.Time
  end

  @required_attrs ~w[performed_during]a
  def changeset(data \ %__MODULE__{}, attrs) do
    data
    |> cast(attrs, @required_attrs)
    |> validate_required(@required_attrs)
  end
end
```

# `cast`

Converts user-provided data (for example from a form) to the Elixir term.

# `dump`

Converts the Elixir term to the Ecto native type.

# `embed_as`

Declares than when used in embedded schemas, the type will be dumped before being encoded.

# `equal?`

Checks if two terms are equal.

# `load`

Converts the Ecto native type to the Elixir term.

# `type`

Declares the native type that will be used in the database.

# `t`

```elixir
@type t() :: %Ecto.DateTimeRange.Time{end_at: Time.t(), start_at: Time.t()}
```

# `contains?`

```elixir
@spec contains?(t(), DateTime.t() | NaiveDateTime.t() | Time.t()) :: boolean()
```

Returns true or false depending on whether the time is falls within the
specified range. **Note:** this assumes that the range is in the same time zone as
whatever time or date time it is compared against.

## Example

```
iex> import Ecto.DateTimeRange
...>
iex> Ecto.DateTimeRange.Time.contains?(~t[01:00:00..02:00:00]T, ~T[00:00:00])
false
iex> Ecto.DateTimeRange.Time.contains?(~t[01:00:00..02:00:00]T, ~T[01:00:00])
true
iex> Ecto.DateTimeRange.Time.contains?(~t[01:00:00..02:00:00]T, ~T[01:59:59])
true
iex> Ecto.DateTimeRange.Time.contains?(~t[01:00:00..02:00:00]T, ~T[02:00:00])
false
...>
iex> Ecto.DateTimeRange.Time.contains?(~t[01:00:00..02:00:00]T, ~N[2022-01-01T00:00:00])
false
iex> Ecto.DateTimeRange.Time.contains?(~t[01:00:00..02:00:00]T, ~N[2022-01-01T01:00:00])
true
...>
iex> Ecto.DateTimeRange.Time.contains?(~t[01:00:00..02:00:00]T, ~U[2022-01-01T00:00:00Z])
false
iex> Ecto.DateTimeRange.Time.contains?(~t[01:00:00..02:00:00]T, ~U[2022-01-01T01:00:00Z])
true
```

# `parse`

```elixir
@spec parse(binary()) :: {:ok, t()} | {:error, term()}
```

Create an `Ecto.DateTimeRange.Time` from two ISO8601 strings.

## Example

```
iex> Ecto.DateTimeRange.Time.parse("00:01:00..00:01:01")
{:ok, %Ecto.DateTimeRange.Time{start_at: ~T[00:01:00], end_at: ~T[00:01:01]}}

iex> Ecto.DateTimeRange.Time.parse("00:01:00..later")
{:error, "Unable to parse Time(s) from input"}
```

---

*Consult [api-reference.md](api-reference.md) for complete listing*
