bitwalker / timex

A complete date/time library for Elixir projects.
https://hexdocs.pm/timex
MIT License
1.76k stars 379 forks source link

Timex fails to pick up timezone on TrueOS (and possibly FreeBSD too) #521

Open javobalazs opened 5 years ago

javobalazs commented 5 years ago

Steps to reproduce

iex> Timex.local()

Description of issue

iex(5)> Timex.local()
** (MatchError) no match of right hand side value: nil
    (timex) lib/timezone/timezone_local.ex:123: Timex.Timezone.Local.localtz/2
    (timex) lib/timezone/timezone_local.ex:58: Timex.Timezone.Local.lookup/1
    (timex) lib/timezone/timezone.ex:53: Timex.Timezone.local/1
    (timex) lib/timex.ex:64: Timex.local/0

Workaround

$ sudo -s
# echo Europe/Budapest > /etc/timezone

Environment

The proper timezone had been configured to TrueOS with tzsetup, but this doesn't generate an /etc/timezone file. This information is recorded in /var/db/zoneinfo. Erlang and Elixir had been compiled from source. I used elixir-1.8.1 and otp_src_21.2.

$ cat /var/db/zoneinfo
Europe/Budapest
$ uname -a
FreeBSD some_server 13.0-CURRENT FreeBSD 13.0-CURRENT fbd2a3ef6(HEAD) GENERIC  amd64
$ erl
Erlang/OTP 21 [erts-10.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe]
Eshell V10.2  (abort with ^G)
$ iex
Erlang/OTP 21 [erts-10.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe]
Interactive Elixir (1.8.1) - press Ctrl+C to exit (type h() ENTER for help)
$ mix deps.tree
...
        ├── timex ~> 3.4 (Hex package)
        │   ├── combine ~> 0.10 (Hex package)
        │   ├── gettext ~> 0.10 (Hex package)
        │   └── tzdata ~> 0.1.8 or ~> 0.5 (Hex package)
        │       └── hackney ~> 1.0 (Hex package)
        │           ├── certifi 2.4.2 (Hex package)
        │           │   └── parse_trans ~>3.3 (Hex package)
        │           ├── idna 6.0.0 (Hex package)
        │           │   └── unicode_util_compat 0.4.1 (Hex package)
        │           ├── metrics 1.0.1 (Hex package)
        │           ├── mimerl 1.0.2 (Hex package)
        │           └── ssl_verify_fun 1.1.4 (Hex package)
$ cat mix.lock
%{
...
  "certifi": {:hex, :certifi, "2.4.2", "75424ff0f3baaccfd34b1214184b6ef616d89e420b258bb0a5ea7d7bc628f7f0", [:rebar3],   "combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm"},
  "gettext": {:hex, :gettext, "0.16.0", "4a7e90408cef5f1bf57c5a39e2db8c372a906031cc9b1466e963101cb927dafc", [:mix], [], "hexpm"},
  "hackney": {:hex, :hackney, "1.14.3", "b5f6f5dcc4f1fba340762738759209e21914516df6be440d85772542d4a5e412", [:rebar3], [{:certifi, "2.4.2", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.4", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"},
  "idna": {:hex, :idna, "6.0.0", "689c46cbcdf3524c44d5f3dde8001f364cd7608a99556d8fbd8239a5798d4c10", [:rebar3], [{:unicode_util_compat, "0.4.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"},
  "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"},
  "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm"},
  "parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm"},
  "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.4", "f0eafff810d2041e93f915ef59899c923f4568f4585904d010387ed74988e77b", [:make, :mix, :rebar3], [], "hexpm"},
  "timex": {:hex, :timex, "3.4.1", "e63fc1a37453035e534c3febfe9b6b9e18583ec7b37fd9c390efdef97397d70b", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 0.1.8 or ~> 0.5", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm"},
  "tzdata": {:hex, :tzdata, "0.5.19", "7962a3997bf06303b7d1772988ede22260f3dae1bf897408ebdac2b4435f4e6a", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"},
  "unicode_util_compat": {:hex, :unicode_util_compat, "0.4.1", "d869e4c68901dd9531385bb0c8c40444ebf624e60b6962d95952775cac5e90cd", [:rebar3], [], "hexpm"},
}
silva96 commented 5 years ago

maybe it is related to this: https://github.com/lau/tzdata/issues/79

There was a typo in tzdata from iana. that broke the parsing method and made impossible to create tzdata ets table, hence, no timezones are available.

javobalazs commented 5 years ago

Not related, although the bug is probably in tzdata (or it should be fixed in tzdata?), but this is my speculation. Perhaps someone who is knowledgeable in timex should point it out. If tzdata is the culprit, of course I will raise the issue there. Again, the specific problem is that in certain Unices time zone information is in different places where timex (or tzdata) expects it.

lau commented 5 years ago

Not related, although the bug is probably in tzdata

It's not.

maybe it is related to this: lau/tzdata#79 There was a typo in tzdata from iana. that broke the parsing method and made impossible to create tzdata ets table, hence, no timezones are available.

It's not related to that. That only has to do with updating to new data, which happens in a separate process. Tzdata would just keep using the existing older data for time zones that ships with the tzdata hex package.

Hope this helps.

javobalazs commented 5 years ago

Thanks for the comment. The fundamental problem is with the timezone file of the operating system (the file that contains the local timezone). TrueOS puts it in a different place, and someone (either tzdata or timex, or even something else) doesn't pick that up. I don't know the mechanism how the local timezone info gets loaded in timex, and probably it would take ages to me to discover it, that's why I've posted here. Nevertheless, I discovered the root cause of the failure, see above.