# `Machete.DateTimeMatcher`
[🔗](https://github.com/mtrudel/machete/blob/main/lib/machete/matchers/datetime_matcher.ex#L1)

Defines a matcher that matches DateTime values

# `opts`

```elixir
@type opts() :: [
  precision: 0..6,
  time_zone: Calendar.time_zone() | :utc,
  exactly: DateTime.t(),
  roughly: DateTime.t() | :now,
  epsilon: integer() | {integer(), integer()},
  before: DateTime.t() | :now,
  after: DateTime.t() | :now
]
```

Describes the arguments that can be passed to this matcher

# `t`

```elixir
@opaque t()
```

Describes an instance of this matcher

# `datetime`

```elixir
@spec datetime(opts()) :: t()
```

Matches against DateTime values

Takes the following arguments:

* `precision`: Requires the matched DateTime to have the specified microsecond precision
* `time_zone`: Requires the matched DateTime to have the specified time zone. The atom `:utc`
  can be used to specify the "Etc/UTC" time zone
* `exactly`: Requires the matched DateTime to be exactly equal to the specified DateTime
* `roughly`: Requires the matched DateTime to be within `epsilon` seconds of the specified DateTime.
  The atom `:now` can be used to use the current time as the specified DateTime
* `epsilon`: The bound(s) to use when determining how close (in microseconds) the matched
  DateTime time needs to be to `roughly`. Can be specified as a single integer that is used for both lower
  and upper bounds, or a tuple consisting of distinct lower and upper bounds. If not specified,
  defaults to 10_000_000 microseconds (10 seconds)
* `before`: Requires the matched DateTime to be before or equal to the specified DateTime. The
  atom `:now` can be used to use the current time as the specified DateTime
* `after`: Requires the matched DateTime to be after or equal to the specified DateTime. The
  atom `:now` can be used to use the current time as the specified DateTime

Examples:

    iex> assert DateTime.utc_now() ~> datetime()
    true

    iex> assert DateTime.utc_now() ~> datetime(precision: 6)
    true

    iex> assert DateTime.utc_now() ~> datetime(time_zone: :utc)
    true

    iex> assert DateTime.utc_now() ~> datetime(time_zone: "Etc/UTC")
    true

    iex> assert ~U[2020-01-01 00:00:00.000000Z] ~> datetime(exactly: ~U[2020-01-01 00:00:00.000000Z])
    true

    iex> assert DateTime.utc_now() ~> datetime(roughly: :now)
    true

    iex> assert ~U[2020-01-01 00:00:00.000000Z] ~> datetime(roughly: ~U[2020-01-01 00:00:05.000000Z])
    true

    iex> assert ~U[2020-01-01 00:00:00.000000Z] ~> datetime(roughly: ~U[2020-01-01 00:00:10.000000Z], epsilon: 10000000)
    true

    iex> assert ~U[2020-01-01 00:00:00.000000Z] ~> datetime(roughly: ~U[2020-01-01 00:00:10.000000Z], epsilon: {10000000, 5000000})
    true

    iex> refute ~U[2020-01-01 00:00:00.000000Z] ~> datetime(roughly: ~U[2020-01-01 00:00:10.000001Z], epsilon: 10000000)
    false

    iex> refute ~U[2020-01-01 00:00:00.000000Z] ~> datetime(roughly: ~U[2020-01-01 00:00:10.000001Z], epsilon: {10000000, 5000000})
    false

    iex> assert ~U[2020-01-01 00:00:00.000000Z] ~> datetime(before: :now)
    true

    iex> assert ~U[2020-01-01 00:00:00.000000Z] ~> datetime(before: ~U[3000-01-01 00:00:00.000000Z])
    true

    iex> assert ~U[3000-01-01 00:00:00.000000Z] ~> datetime(after: :now)
    true

    iex> assert ~U[3000-01-01 00:00:00.000000Z] ~> datetime(after: ~U[2020-01-01 00:00:00.000000Z])
    true

---

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