Resolve timezones from a location using data from the timezone-boundary-builder project.
Add tz_world to your list of dependencies in mix.exs:
def deps do
[
{:tz_world, "~> 0.5.0"}
]
endAfter adding TzWorld as a dependency, run mix deps.get to install it. Then
run mix tz_world.update to install the timezone data.
NOTE No data is installed with the package and until the data is installed
with mix tz_world.update all calls to TzWorld.timezone_at/1 will return
{:error, :time_zone_not_found}.
There is no mandatory configuration required however two options may be
configured in config.exs:
config :tz_world,
# The default is the `priv` directory of `:tz_world`
data_dir: "geodata/directory",
# The default is either the trust store included in the
# libraries `CAStore` or `certifi` or the platform
# trust store.
cacertfile: "path/to/ca_trust_store"TzWorld provides alternative strategies for managing access to the backend
data. Each backend is implemented as a GenServer that needs to be either
manually started with BackendModule.start_link/1 or preferably added to your
application's supervision tree.
The recommended backend is TzWorld.Backend.EtsWithIndexCache.
For example:
defmodule MyApp.Application do
@moduledoc false
use Application
def start(_type, _args) do
children = [
...
TzWorld.Backend.DetsWithIndexCache
]
opts = [strategy: :one_for_one, name: MyApp.Supervisor]
Supervisor.start_link(children, opts)
end
endThe following backends are available:
-
TzWorld.Backend.Memorywhich retains all data in memory for fast (but not fastest) performance at the expense of using approximately 1GB of memory -
TzWorld.Backend.Detswhich uses Erlang's:detsdata store. This uses negligible memory at the expense of slow access times (approximately 500ms in testing) -
TzWorld.Backend.DetsWithIndexCachewhich balances memory usage and performance. This backend is recommended in most situations since its performance is similar toTzWorld.Backend.Memory(about 5% slower in testing) and uses about 25Mb of memory -
TzWorld.Backend.Etswhich uses:etsfor storage. With the default settings of:compressedfor the:etstable its memory consumption is about 512Mb but with access that is over 20 times slower thanTzWorld.Backend.DetsWithIndexCache -
TzWorld.Backend.EtsWithIndexCachewhich uses:etsfor storage with an additional in-memory cache of the bounding boxes. This still uses about 512Mb but is faster than any of the other backends by about 40%
Installing tz_world from source or from hex does not include the timezones
Geo JSON data. The data is required and to install or update it run:
mix tz_world.updateThis task will download, transform, zip and store the timezones Geo data. Depending on internet and computer speed this may take a few minutes.
From time-to-time the timezones Geo JSON data is updated in the upstream
project. The
mix task mix tz_world.update will update the data if it is available. This
task can be run at any time, it will detect when new data is available and only
download it when a new release is available.
A running application can also be instructed to reload the data by executing
TzWorld.reload_timezone_data.
The primary API is TzWorld.timezone_at. It takes either a Geo.Point struct
or a longitude and latitude in degrees. Note the parameter order:
longitude, latitude. It also takes and optional second parameter,
backend, which must be one of the configured and running backend modules. By
default timezone_at/2 will detect a running backend and will raise an
exception if no running backend is found.
iex> TzWorld.timezone_at(%Geo.Point{coordinates: {3.2, 45.32}})
{:ok, "Europe/Paris"}
iex> TzWorld.timezone_at({3.2, 45.32})
{:ok, "Europe/Paris"}
iex> TzWorld.timezone_at(%Geo.PointZ{coordinates: {-74.006, 40.7128, 0.0}})
{:ok, "America/New_York"}
iex> TzWorld.timezone_at(%Geo.Point{coordinates: {1.3, 65.62}})
{:error, :time_zone_not_found}