# `Membrane.Time`
[🔗](https://github.com/membraneframework/membrane-core/blob/v1.2.7/lib/membrane/time.ex#L1)

Module containing functions needed to perform handling of time.

Membrane always internally uses nanosecond as a time unit. This is how all time
units should represented in the code unless there's a good reason to act
differently.

Please note that Erlang VM may internally use different units and that may
differ from platform to platform. Still, unless you need to perform calculations
that do not touch hardware clock, you should use Membrane units for consistency.

# `non_neg`

```elixir
@type non_neg() :: non_neg_integer()
```

# `t`

```elixir
@type t() :: integer()
```

The time represented in Membrane's time units.

# `as_days`

```elixir
@spec as_days(t(), mode :: :round | :exact) :: integer() | Ratio.t()
```

Returns time in days.

If the `mode` argument is set to `:exact` (default), the result is
represented as a rational number. Otherwise, if the `mode` is
`:round`, the result is rounded to the nearest integer.

# `as_hours`

```elixir
@spec as_hours(t(), mode :: :round | :exact) :: integer() | Ratio.t()
```

Returns time in hours.

If the `mode` argument is set to `:exact` (default), the result is
represented as a rational number. Otherwise, if the `mode` is
`:round`, the result is rounded to the nearest integer.

# `as_microseconds`

```elixir
@spec as_microseconds(t(), mode :: :round | :exact) :: integer() | Ratio.t()
```

Returns time in microseconds.

If the `mode` argument is set to `:exact` (default), the result is
represented as a rational number. Otherwise, if the `mode` is
`:round`, the result is rounded to the nearest integer.

# `as_milliseconds`

```elixir
@spec as_milliseconds(t(), mode :: :round | :exact) :: integer() | Ratio.t()
```

Returns time in milliseconds.

If the `mode` argument is set to `:exact` (default), the result is
represented as a rational number. Otherwise, if the `mode` is
`:round`, the result is rounded to the nearest integer.

# `as_minutes`

```elixir
@spec as_minutes(t(), mode :: :round | :exact) :: integer() | Ratio.t()
```

Returns time in minutes.

If the `mode` argument is set to `:exact` (default), the result is
represented as a rational number. Otherwise, if the `mode` is
`:round`, the result is rounded to the nearest integer.

# `as_nanoseconds`

```elixir
@spec as_nanoseconds(t(), mode :: :round | :exact) :: integer() | Ratio.t()
```

Returns time in nanoseconds.

If the `mode` argument is set to `:exact` (default), the result is
represented as a rational number. Otherwise, if the `mode` is
`:round`, the result is rounded to the nearest integer.

# `as_seconds`

```elixir
@spec as_seconds(t(), mode :: :round | :exact) :: integer() | Ratio.t()
```

Returns time in seconds.

If the `mode` argument is set to `:exact` (default), the result is
represented as a rational number. Otherwise, if the `mode` is
`:round`, the result is rounded to the nearest integer.

# `day`

```elixir
@spec day() :: t()
```

Returns one day in `Membrane.Time` units.

# `days`

```elixir
@spec days(integer() | Ratio.t()) :: t()
```

Returns given amount of days in `Membrane.Time` units.

# `divide_by_timebase`

```elixir
@spec divide_by_timebase(number() | Ratio.t(), number() | Ratio.t()) :: integer()
```

Divides timestamp by a timebase. The result is rounded to the nearest integer.

## Examples:
    iex> timestamp = 10 |> Membrane.Time.seconds()
    iex> timebase = Ratio.new(Membrane.Time.second(), 30)
    iex> Membrane.Time.divide_by_timebase(timestamp, timebase)
    300

# `from_datetime`

```elixir
@spec from_datetime(DateTime.t()) :: t()
```

Converts `DateTime` to `Membrane.Time` units.

# `from_iso8601!`

```elixir
@spec from_iso8601!(String.t()) :: t()
```

Converts iso8601 string to `Membrane.Time` units.
If `value` is invalid, throws match error.

# `from_ntp_timestamp`

```elixir
@spec from_ntp_timestamp(ntp_time :: &lt;&lt;_::64&gt;&gt;) :: t()
```

Converts NTP timestamp (time since 0h on 1st Jan 1900) into Unix timestamp
(time since 1st Jan 1970) represented in `Membrane.Time` units.

NTP timestamp uses fixed point representation with the integer part in the first 32 bits
and the fractional part in the last 32 bits.

# `hour`

```elixir
@spec hour() :: t()
```

Returns one hour in `Membrane.Time` units.

# `hours`

```elixir
@spec hours(integer() | Ratio.t()) :: t()
```

Returns given amount of hours in `Membrane.Time` units.

# `inspect`

```elixir
@spec inspect(t()) :: String.t()
```

Returns string representation of result of `to_code/1`.

# `is_time`
*macro* 

Checks whether a value is `Membrane.Time.t`.

# `microsecond`

```elixir
@spec microsecond() :: t()
```

Returns one microsecond in `Membrane.Time` units.

# `microseconds`

```elixir
@spec microseconds(integer() | Ratio.t()) :: t()
```

Returns given amount of microseconds in `Membrane.Time` units.

# `millisecond`

```elixir
@spec millisecond() :: t()
```

Returns one millisecond in `Membrane.Time` units.

# `milliseconds`

```elixir
@spec milliseconds(integer() | Ratio.t()) :: t()
```

Returns given amount of milliseconds in `Membrane.Time` units.

# `minute`

```elixir
@spec minute() :: t()
```

Returns one minute in `Membrane.Time` units.

# `minutes`

```elixir
@spec minutes(integer() | Ratio.t()) :: t()
```

Returns given amount of minutes in `Membrane.Time` units.

# `monotonic_time`

```elixir
@spec monotonic_time() :: t()
```

Returns current monotonic time based on `System.monotonic_time/0`
in `Membrane.Time` units.

# `nanosecond`

```elixir
@spec nanosecond() :: t()
```

Returns one nanosecond in `Membrane.Time` units.

# `nanoseconds`

```elixir
@spec nanoseconds(integer() | Ratio.t()) :: t()
```

Returns given amount of nanoseconds in `Membrane.Time` units.

# `native_unit`

```elixir
@spec native_unit() :: t()
```

Returns one VM native unit in `Membrane.Time` units.

# `native_units`

```elixir
@spec native_units(integer()) :: t()
```

Returns given amount of VM native units in `Membrane.Time` units.

# `os_time`

```elixir
@spec os_time() :: t()
```

Returns current POSIX time of operating system based on `System.os_time/0`
in `Membrane.Time` units.

This time is not monotonic.

# `pretty_duration`

```elixir
@spec pretty_duration(t()) :: String.t()
```

Returns duration as a string with unit. Chosen unit is the biggest possible
that doesn't involve precission loss.

## Examples

    iex> import Membrane.Time
    iex> 10 |> milliseconds() |> pretty_duration()
    "10 ms"
    iex> 60_000_000 |> microseconds() |> pretty_duration()
    "1 min"
    iex> 2 |> nanoseconds() |> pretty_duration()
    "2 ns"

# `pretty_now`

```elixir
@spec pretty_now() :: String.t()
```

Returns current time in pretty format (currently iso8601), as string
Uses `os_time/0` under the hood.

# `second`

```elixir
@spec second() :: t()
```

Returns one second in `Membrane.Time` units.

# `seconds`

```elixir
@spec seconds(integer() | Ratio.t()) :: t()
```

Returns given amount of seconds in `Membrane.Time` units.

# `to_code`

```elixir
@spec to_code(t()) :: Macro.t()
```

Returns quoted code producing given amount time. Chosen unit is the biggest possible
that doesn't involve precission loss.

## Examples

    iex> import Membrane.Time
    iex> 10 |> milliseconds() |> to_code() |> Macro.to_string()
    quote do 10 |> Membrane.Time.milliseconds() end |> Macro.to_string()
    iex> 60_000_000 |> microseconds() |> to_code() |> Macro.to_string()
    quote do Membrane.Time.minute() end |> Macro.to_string()
    iex> 2 |> nanoseconds() |> to_code() |> Macro.to_string()
    quote do 2 |> Membrane.Time.nanoseconds() end |> Macro.to_string()

# `to_datetime`

```elixir
@spec to_datetime(t()) :: DateTime.t()
```

Returns time as a `DateTime` struct. TimeZone is set to UTC.

# `to_iso8601`

```elixir
@spec to_iso8601(t()) :: String.t()
```

Returns time as a iso8601 string.

# `to_native_units`

```elixir
@spec to_native_units(t()) :: integer()
```

Returns time in VM native units. Rounded using Kernel.round/1.

# `to_ntp_timestamp`

```elixir
@spec to_ntp_timestamp(timestamp :: t()) :: &lt;&lt;_::64&gt;&gt;
```

Converts the timestamp into NTP timestamp. May introduce small rounding errors.

# `vm_time`

```elixir
@spec vm_time() :: t()
```

Returns current Erlang VM system time based on `System.system_time/0`
in `Membrane.Time` units.

It is the VM view of the `os_time/0`. They may not match in case of time warps.
It is not monotonic.

---

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