Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
# Changelog for Tzdata

## Unreleased
## [1.2.0] - 2026-09-13

### Added

- Parse the IANA `factory` source file, adding the placeholder `Factory`
zone (previously omitted) to the zone list.

### Changed

- Now requires Elixir 1.12 or greater instead of 1.9 or greater.
- Hackney is no longer a mandatory dependency. When `:http_client` isn't
configured explicitly, Tzdata now automatically picks the best available
HTTP client: the built-in `:httpc`, verifying certificates via
Expand All @@ -12,6 +18,16 @@
dependency; otherwise `:httpc` is still used but automatic updates are
skipped with a warning rather than downloading without verification. See
the README's "HTTP client and security" section for details.
- Debug log messages for downloading new data now include the name of the
HTTP client in use (e.g. `httpc` or `hackney`).
- tzdata release version shipped with this library is now 2026d instead of 2026c.

### Deprecated

- Hackney support is deprecated and will be removed in a future release.
Using `Tzdata.HTTPClient.Hackney` now logs a warning. It is strongly
recommended to use Erlang/OTP 25 or higher, where the built-in `:httpc`
client is used by default and no HTTP client dependency is needed.

### Fixed

Expand Down
61 changes: 12 additions & 49 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,24 @@ Tzdata. The [timezone database](https://www.iana.org/time-zones) in Elixir.

Extracted from the [Calendar](https://github.com/lau/calendar) library.

As of version 1.1.5 the tz release 2026c is included in the package.
As of version 1.2.0 the tz release 2026d is included in the package.

When a new release is out, it will be automatically downloaded at runtime.

The tz release version in use can be verified with the following function:

```elixir
iex> Tzdata.tzdata_version
"2026c"
"2026d"
```

## Getting started

To use the Tzdata library with Elixir 1.8+, add it to the dependencies in your mix file:
To use the Tzdata library with Elixir 1.12+, add it to the dependencies in your mix file:

```elixir
defp deps do
[ {:tzdata, "~> 1.1"}, ]
[ {:tzdata, "~> 1.2"}, ]
end
```

Expand Down Expand Up @@ -97,53 +97,16 @@ For use with [Calendar](https://github.com/lau/calendar) you can still
specify tzdata ~> 0.1.7 in your mix.exs file in case you experience problems
using version ~> 0.5.20

## Hackney dependency and security
## HTTP client and security

Tzdata depends on Hackney in order to do HTTPS requests to get new updates. This is done because Erlang's built in HTTP client `httpc` does not verify SSL certificates when doing HTTPS requests. Hackney verifies the certificate of IANA when getting new tzdata releases from IANA.
Hackney is no longer a required dependency. It is strongly recommended to
use Erlang/OTP 25 or higher for security reasons. With OTP 25+, Tzdata
uses the built-in `httpc` client by default, which can verify certificates
without any extra dependencies.

### New unreleased feature

The following describes an unreleased change: Hackney is becoming an
optional dependency. This section documents how it will work once
released; until then, in the released version, Hackney is still a
required dependency as described above.

Tzdata needs to do HTTPS requests in order to check for and download new
tzdata releases from IANA, and it takes care to verify the certificate of
the server it talks to.

By default, if you don't configure `:http_client` yourself, Tzdata picks
one automatically:

1. If Erlang's built-in `:httpc` client can verify certificates on the
running Erlang/OTP version — i.e. `:public_key.cacerts_get/0` is
available (OTP 25+) and actually returns the operating system's trusted
CA certificates — Tzdata uses it. This requires no extra dependencies.
2. Otherwise, if Hackney is present as a dependency, Tzdata uses
`Tzdata.HTTPClient.Hackney` instead.
3. Otherwise, Tzdata falls back to the `:httpc` client anyway, but since it
cannot verify certificates it will skip automatic updates and log a
warning rather than download without verification.

So on Erlang/OTP 25+ you don't need Hackney at all. On older Erlang/OTP
versions, add Hackney (or another HTTP client) as a dependency and Tzdata
will pick it up automatically — or configure it explicitly:

```elixir
defp deps do
[
{:tzdata, "~> 1.1"},
{:hackney, "~> 1.17 or ~> 4.0"}
]
end
```

```elixir
config :tzdata, :http_client, Tzdata.HTTPClient.Hackney
```

A different HTTP client can also be plugged in by implementing the
`Tzdata.HTTPClient` behaviour and configuring `:http_client` accordingly.
Hackney can still be used on older OTP versions, but this is not
recommended. Hackney support is deprecated and will be removed in a future
release.

## Documentation

Expand Down
23 changes: 22 additions & 1 deletion lib/tzdata/http_client/hackney.ex
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
defmodule Tzdata.HTTPClient.Hackney do
@moduledoc false
@moduledoc """
HTTP client adapter based on the Hackney library.

Deprecated: Hackney support is deprecated and will be removed in a
future release. Upgrade to Erlang/OTP 25 or later to use the built-in
`Tzdata.HTTPClient.Httpc` client instead, which requires no extra
dependencies. See the README's "HTTP client and security" section for
details.
"""

require Logger

@behaviour Tzdata.HTTPClient

if Code.ensure_loaded?(:hackney) do
@impl true
@deprecated "Hackney support is deprecated, upgrade to Erlang/OTP 25+ to use Tzdata.HTTPClient.Httpc instead"
def get(url, headers, options) do
ensure_started!()

Expand All @@ -25,6 +36,7 @@ defmodule Tzdata.HTTPClient.Hackney do
end

@impl true
@deprecated "Hackney support is deprecated, upgrade to Erlang/OTP 25+ to use Tzdata.HTTPClient.Httpc instead"
def head(url, headers, options) do
ensure_started!()

Expand All @@ -38,6 +50,15 @@ defmodule Tzdata.HTTPClient.Hackney do
# just because it's compiled and available. Start it lazily here instead
# of requiring users to add `:hackney` to their own `extra_applications`.
defp ensure_started! do
Logger.warning("""
Tzdata is using Hackney as its HTTP client. Hackney support is
deprecated and will be removed in a future release.

Upgrade to Erlang/OTP 25 or later to use the built-in :httpc client
instead, which requires no extra dependencies. See the README's
"HTTP client and security" section for details.
""")

case Application.ensure_all_started(:hackney) do
{:ok, _apps} -> :ok
{:error, reason} -> raise "failed to start :hackney application: #{inspect(reason)}"
Expand Down
4 changes: 2 additions & 2 deletions mix.exs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
defmodule Tzdata.Mixfile do
use Mix.Project

@version "1.1.5"
@version "1.2.0"

def project do
[
app: :tzdata,
name: "tzdata",
version: @version,
elixir: "~> 1.9",
elixir: "~> 1.12",
package: package(),
description: description(),
deps: deps(),
Expand Down
Loading