README.md

# TimeZoneInfo
[![Hex.pm](https://img.shields.io/hexpm/v/time_zone_info.svg)](https://hex.pm/packages/time_zone_info)
[![Build Status](https://travis-ci.org/hrzndhrn/time_zone_info.svg?branch=master)](https://travis-ci.org/hrzndhrn/time_zone_info)
[![Coverage Status](https://coveralls.io/repos/github/hrzndhrn/time_zone_info/badge.svg?branch=master)](https://coveralls.io/github/hrzndhrn/time_zone_info?branch=master)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

Time zone support for Elixir by using the
[IANA Time Zone Database](https://www.iana.org/time-zones).

## Installation

The package can be installed by adding `time_zone_info` to your list of
dependencies in `mix.exs`:

```elixir
def deps do
  [
    {:time_zone_info, "~> 0.2"}
  ]
end
```

## Usage

After installation, `TimeZoneInfo` can be used as follows.
```
iex> TimeZoneInfo.iana_version
"2019c"
iex> TimeZoneInfo.time_zones() |> Enum.take(3)
["Africa/Abidjan", "Africa/Accra", "Africa/Addis_Ababa"]
iex> TimeZoneInfo.period_from_utc(~N[2020-03-29 01:30:00], "Europe/Berlin")
{:ok, {3600, 3600, "CEST"}}
```

In combination with `DateTime` and `Calendar`:
```
iex> {:ok, berlin} = DateTime.from_naive(
...>   ~N[2020-03-29 01:30:00],
...>   "Europe/Berlin",
...>    TimeZoneInfo.TimeZoneDatabase)
{:ok, #DateTime<2020-03-29 01:30:00+01:00 CET Europe/Berlin>}
iex> Calendar.put_time_zone_database(TimeZoneInfo.TimeZoneDatabase)
:ok
iex> DateTime.shift_zone(berlin, "America/New_York")
{:ok, #DateTime<2020-03-28 20:30:00-04:00 EDT America/New_York>}
```

Instead of the line
`Calendar.put_time_zone_database(TimeZoneInfo.TimeZoneDatabase)` you can also
specify the following entry in the configuration.
```
config :elixir, :time_zone_database, TimeZoneInfo.TimeZoneDatabase
```

For more information how to configure `TimeZoneInfo` see
[Config](https://hexdocs.pm/time_zone_info/config.html). The site shows how to
enable automated updates, filter time zones, and add custom `behaviour`s.

## Benchmarks

The benchmarks can be executed with `mix bench`.

A [benchmark](bench/README.md) to compare `TimeZoneInfo` with `Tzdata` and `Tz`
for the execution of `TimeZoneDatabase.time_zone_periods_from_wall_datetime/2`.

A [benchmark](bench/trnasformer.md) to measure the speed of the transformation
of the raw IANA data to the required data in runtime.

## Differences to Tzdata and Tz

There are some differences to `Tzdata` and `Tz`. The list shows differences to
`Tzdata` and/or `Tz`.

- Use of `:persitent_term` with an optional use of `:ets`.
- Persisting data in
  [External Term Format](http://erlang.org/doc/apps/erts/erl_ext_dist.html)
- The data persisting is customizable by the behaviour
  `TimeZoneInfo.DataPersistence`.
- Optional download of time zone data in `TimeZoneInfo` format.
- The download is customizable by the behaviour `TimeZoneInfo.Downloader`.
- Filter time zones per config.
- Optional listener that will be called on updates.
- `TimeZoneInfo` calculates periods in the far future by continuation rules.
  Except for time zones that have daylight saving times for Ramadan.

## References

The home of the IANA Time Zone Database: https://www.iana.org/time-zones

Links:
- [Time zone](https://en.wikipedia.org/wiki/Time_zone) - Wikipedia
- [**time**and**date**.com](https://www.timeanddate.com/)
- [WorldTimeServer.com](https://www.worldtimeserver.com/)

Other Elixir implementations:
- [tzdata](https://github.com/lau/tzdata) - Tzdata is a parser and library for
  the tz database.
- [tz](https://github.com/mathieuprog/tz) - Time zone support for Elixir

Other implementations:
- [DateTime::TimeZone](https://github.com/houseabsolute/DateTime-TimeZone) - Perl
  - `TimeZoneInfo` use this module as a checker in the tests.
- [NodaTime](https://nodatime.org/) - A better date and time API for .NET
  - `TimeZonInfo` use some data from this
    [site](https://nodatime.org/tzvalidate/generate?version=2019c) in the tests.