# `Timex.TimezoneInfo`
[🔗](https://github.com/bitwalker/timex/blob/4.0.0/lib/timezone/timezone_info.ex#L1)

All relevant timezone information for a given period, i.e. Europe/Moscow on March 3rd, 2013

Notes:
  - `full_name` is the name of the zone, but does not indicate anything about the current period (i.e. CST vs CDT)
  - `abbreviation` is the abbreviated name for the zone in the current period, i.e. "America/Chicago" on 3/30/15 is "CDT"
  - `offset_std` is the offset in seconds from standard time for this period
  - `offset_utc` is the offset in seconds from UTC for this period

Spec:
  - `day_of_week`: :sunday, :monday, :tuesday, etc
  - `datetime`:    {{year, month, day}, {hour, minute, second}}
  - `from`:      :min | {day_of_week, datetime}, when this zone starts
  - `until`:     :max | {day_of_week, datetime}, when this zone ends

# `datetime`

```elixir
@type datetime() :: {{non_neg_integer(), 1..12, 1..31}, {0..24, 0..59, 0..60}}
```

# `day_of_week`

```elixir
@type day_of_week() ::
  :sunday | :monday | :tuesday | :wednesday | :thursday | :friday | :saturday
```

# `from_constraint`

```elixir
@type from_constraint() :: :min | {day_of_week(), datetime()}
```

# `offset`

```elixir
@type offset() :: -85399..85399
```

# `t`

```elixir
@type t() :: %Timex.TimezoneInfo{
  abbreviation: String.t(),
  from: from_constraint(),
  full_name: String.t(),
  offset_std: offset(),
  offset_utc: offset(),
  until: until_constraint()
}
```

# `until_constraint`

```elixir
@type until_constraint() :: :max | {day_of_week(), datetime()}
```

# `create`

```elixir
@spec create(
  String.t(),
  String.t(),
  offset(),
  offset(),
  from_constraint(),
  until_constraint()
) ::
  t() | {:error, String.t()}
```

Create a custom timezone if a built-in one does not meet your needs.

You must provide the name, abbreviation, offset from UTC, daylight savings time offset,
and the from/until reference points for when the zone takes effect and ends.

To clarify the two offsets, `offset_utc` is the absolute offset relative to UTC,
`offset_std` is the offset to apply to `offset_utc` which gives us the offset from UTC
during daylight savings time for this timezone. If DST does not apply for this zone, simply
set it to 0.

The `from`/`until` reference points must meet the following criteria:

- Be set to `:min` for `from`, or `:max` for `until`, which represents
  "infinity" for the start/end of the zone period
- OR, be a tuple of `{day_of_week, datetime}`, where:
  - `day_of_week` is an atom like `:sunday`
  - `datetime` is an Erlang datetime tuple, e.g. `{{2016,10,8},{2,0,0}}`

**IMPORTANT**: Offsets are in seconds, not minutes. If you do not ensure they
are in the correct unit, runtime errors or incorrect results are probable.

## Examples

    iex> Elixir.Timex.TimezoneInfo.create("Etc/Test", "TST", 120*60, 0, :min, :max)
    %TimezoneInfo{full_name: "Etc/Test", abbreviation: "TST", offset_std: 7200, offset_utc: 0, from: :min, until: :max}
    ...> Elixir.Timex.TimezoneInfo.create("Etc/Test", "TST", 24*60*60, 0, :min, :max)
    {:error, "invalid timezone offset '86400'"}

# `format_offset`

```elixir
@spec format_offset(tzinfo :: t()) :: String.t()
```

Formats the offset of a `Timex.TimezoneInfo` struct.

## Examples

    iex> tzinfo = Timex.Timezone.get("Etc/Greenwich", ~U[2022-01-01 00:00:00Z])
    ...> Elixir.Timex.TimezoneInfo.format_offset(tzinfo)
    "+00:00:00"

    iex> tzinfo = Timex.Timezone.get("Africa/Nairobi", ~U[2022-01-01 00:00:00Z])
    ...> Elixir.Timex.TimezoneInfo.format_offset(tzinfo)
    "+03:00:00"

    iex> tzinfo = Timex.Timezone.get("America/New_York", ~U[2022-01-01 00:00:00Z])
    ...> Elixir.Timex.TimezoneInfo.format_offset(tzinfo)
    "-05:00:00"

# `from_datetime`

---

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