Coder Social home page Coder Social logo

tzdata's Introduction

Tzdata

Build Status Hex.pm version Hex.pm downloads

Tzdata. The timezone database in Elixir.

Extracted from the Calendar library.

As of version 1.1.1 the tz release 2021e 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:

iex> Tzdata.tzdata_version
"2021e"

Getting started

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

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

In your application you can choose to globally configure Elixir to use Tzdata. This can be done by putting the following line in the config file of your application:

config :elixir, :time_zone_database, Tzdata.TimeZoneDatabase

That's it!

That allows you to use the Elixir standard library to use Tzdata to do time zone calculations. One example is getting the current time in a certain time zone:

iex> DateTime.now("Europe/Copenhagen")
{:ok, #DateTime<2018-11-30 20:51:59.076524+01:00 CET Europe/Copenhagen>}

If you do not want Elixir to have a time zone database globally defined you can instead pass the module name Tzdata.TimeZoneDatabase directly to the functions that need a time zone database:

DateTime.now("Europe/Copenhagen", Tzdata.TimeZoneDatabase)

Data directory and releases

The library uses a file directory to store data. By default this directory is priv. In some cases you might want to use a different directory. For instance when using releases this is recommended. If so, create the directory and make sure Elixir can read and write to it. Then use elixir config files like this to tell Tzdata to use that directory:

config :tzdata, :data_dir, "/etc/elixir_tzdata_data"

Add the release_ets directory from priv to that directory containing the 20xxx.ets file that ships with this library.

For instance with this config: config :tzdata, :data_dir, "/etc/elixir_tzdata_data" an .ets file such as /etc/elixir_tzdata_data/release_ets/2017b.ets should be present.

Automatic data updates

By default Tzdata will poll for timezone database updates every day. In case new data is available, Tzdata will download it and use it.

This feature can be disabled with the following configuration:

config :tzdata, :autoupdate, :disabled

If the autoupdate setting is set to disabled, one has to manually put updated .ets files in the release_ets sub-dir of the "data_dir" (see the "Data directory and releases" section above). When IANA releases new versions of the time zone data, this Tzdata library can be used to generate a new .ets file containing the new data.

Changes from 0.1.x to 0.5.x

The 0.5.1+ versions uses ETS tables and automatically polls the IANA servers for updated data. When a new version of the timezone database is available, it is automatically downloaded and used.

For use with 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

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.

Documentation

Documentation can be found at http://hexdocs.pm/tzdata/

When new timezone data is released

IANA releases new versions of the timezone database frequently.

For users of Tzdata version 0.5.x+ the new database will automatically be downloaded, parsed, saved and used in place of the old data.

License

The tzdata Elixir library is released under the MIT license. See the LICENSE file.

The tz database files (found in the source_data directory of early versions) is public domain.

tzdata's People

Contributors

adamu avatar edennis avatar enerick avatar fabienhenon avatar hoyon avatar isaacsanders avatar jarrodmoldrich avatar jbodah avatar lau avatar lostkobrakai avatar lowks avatar madsheep avatar mathieuprog avatar mdoza avatar milmazz avatar msch avatar paulswartz avatar sasa1977 avatar tbk145 avatar thefirstavenger avatar tsubery avatar vitortrin avatar weisslj avatar wingyplus avatar wojtekmach avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tzdata's Issues

Automatic update failing sometimes

Sometimes the automatic update is failing on my machine (and on a coworkers' machine). I can turn automatic updating off, however I think it would be nice if this error is handled correctly.

2015-10-14 10:45:38.080 [debug] Tzdata downloading new data from https://www.iana.org/time-zones/repository/tzdata-latest.tar.gz 
2015-10-14 10:45:39.148 [debug] Tzdata data downloaded. Release version 2015f.
2015-10-14 10:45:40.728 [error] GenServer Tzdata.EtsHolder terminating
** (MatchError) no match of right hand side value: {:error, :cannot_create_table}
    (tzdata) lib/tzdata/ets_holder.ex:51: Tzdata.EtsHolder.load_ets_table/1
    (tzdata) lib/tzdata/ets_holder.ex:44: Tzdata.EtsHolder.load_release/0
    (tzdata) lib/tzdata/ets_holder.ex:21: Tzdata.EtsHolder.handle_cast/2
    (stdlib) gen_server.erl:615: :gen_server.try_dispatch/4
    (stdlib) gen_server.erl:681: :gen_server.handle_msg/5
    (stdlib) proc_lib.erl:240: :proc_lib.init_p_do_apply/3
Last message: {:"$gen_cast", :new_release_has_been_downloaded}
State: "2015g”

I didn't look any further than this point because I'm unable to reproduce this on command. Maybe you have an idea yourself why this happens.

Compile error: could not stream priv/tmp_downloads/300363//backward: no such file or directory

Hi, I have an error on compilation on CentOS 6.3 with tzdata 0.5.2:

Could you please tell me how to solve it?

Generated ecto app



20:54:13.422 [error] Task #PID<0.1047.0> started from :tzdata_release_updater terminating
** (File.Error) could not stream priv/tmp_downloads/300363//backward: no such file or directory
    (elixir) lib/file/stream.ex:77: anonymous fn/2 in Enumerable.File.Stream.reduce/3
    (elixir) lib/stream.ex:1077: anonymous fn/5 in Stream.resource/3
    (elixir) lib/stream.ex:1240: Enumerable.Stream.do_each/4
    (elixir) lib/enum.ex:1391: Enum.reduce/3
    (elixir) lib/enum.ex:2130: Enum.to_list/1
    (tzdata) lib/tzdata/parser.ex:16: Tzdata.Parser.process_file/1
    (tzdata) lib/tzdata/basic_data_map.ex:8: anonymous fn/2 in Tzdata.BasicDataMap.from_files_in_dir/1
    (elixir) lib/enum.ex:1043: anonymous fn/3 in Enum.map/2
Function: #Function<1.108323131/0 in Tzdata.ReleaseUpdater.init/1>
    Args: []



==> cowlib (compile)

Issue with tzdata

iex(6)> {:ok, mvd } = Calendar.DateTime.from_erl {{2014,10,4},{23,44,32}}, "Etc/UTC"
{:ok, #DateTime<2014-10-04 23:44:32Z>}
iex(7)> mvd |> Calendar.DateTime.shift_zone!("Europe/London")
#DateTime<2014-10-05 00:44:32+01:00 BST Europe/London>
iex(8)> mvd |> Calendar.DateTime.shift_zone!("Europe/Dublin")
#DateTime<2014-10-04 23:44:32+00:00 GMT Europe/Dublin>
iex(9)> 

There is some issue in changing timezone when its Dublin, there is one hour difference between UTC and Dublin time but conversion is not adding day light saving.

Can you guide?

DateTime.now with invalid time zone crashes

I'm using Elixir master and tzdata master.

iex> DateTime.now("America/New_Yor", Tzdata.TimeZoneDatabase)
** (MatchError) no match of right hand side value: {:error, :not_found}
    (tzdata) lib/tzdata.ex:168: Tzdata.periods_for_time/3
    (tzdata) lib/tzdata/time_zone_database.ex:15: Tzdata.TimeZoneDatabase.time_zone_period_from_utc_iso_days/2
    (elixir) lib/calendar/datetime.ex:443: DateTime.shift_zone_for_iso_days_utc/5

Per DateTime.now docs, it should return {:error, :time_zone_not_found} instead.

Unexpected results using Tzdata.TimeZoneDatabase and DateTime.shift_zone

This happens on the summer/winter time change boundary:

iex(57)> datetimes = [datetime1, datetime2, datetime3]
[#DateTime<2018-10-28 00:59:59Z>, #DateTime<2018-10-28 01:00:00Z>,
 #DateTime<2018-10-28 01:00:01Z>]
iex(58)> Enum.map(datetimes, &DateTime.shift_zone(&1, "Europe/Copenhagen"))
[
  ok: #DateTime<2018-10-28 02:59:59+02:00 CEST Europe/Copenhagen>,
  error: :time_zone_not_found,
  ok: #DateTime<2018-10-28 02:00:01+01:00 CET Europe/Copenhagen>
]

I think I should expect #DateTime<2018-10-28 02:00:00+01:00 CET Europe/Copenhagen> for the second element.

I'm guessing it's due to this line:

[] -> {:error, :time_zone_not_found}

ets bottle neck.

I do millions of date time calculations per minute and ets begins to become a bottle neck after a while.
I just spun up a temporary work around using fast global and the semapahore library from discord, i'd love to see something like this make it's way into the library propery, preferably in a way that reduces the number of atoms required.

If you welcome the change and have directives I can begin going over the codebase more and release a more well designed solution for inclusion in future builds.

master...noizu:fg_opt

TZ updates with read only file system

In production we use a read only file system which causes problems when trying to update tzdata. We are running into an infinite loop where the system tries to update => write a file => crash => recover from crash => update. I know that there is an option to turn off auto updating (which we have since done) but I was wondering if there was a better way to engineer updates to the tz info.

Here are two proposals that I think would work:
Based on historical data, it looks like there are only around 9-10 changes to the tz database per year[0]. We could just automate the process of downloading the file and commiting a PR which would also bump the patch level of the library. This would allow people who can't auto update to get the most recent info.

Or

Change the auto update process to not rely on files. I think we should be able to hold everything in memory based on my quick overview of the update process. We lose the benefit of being able to read a cache from disk but I don't really think this is a show stopper in terms of perf since this is an async action anyway.

0: ftp://ftp.iana.org/tz/releases

data_loader.ex does not customize default hackney User-Agent string

Hi,

It looks like the data_loader.ex file does not customize the default user agent. It would be useful to set that to a unique value to politely identify the source of http requests.

Untested code would be something like...
Before:

{:ok, 200, _headers, client_ref}=:hackney.get(url, [], "", [])

After:

tz_ua = [<<"User-Agent: ", "tzdata/", version/binary, " (https://github.com/lau/tzdata)" >>],
{:ok, 200, _headers, client_ref}=:hackney.get(url, tz_ua, "", [])

For the sake of reference easily copy-and-pasted, hackney's default_ua() is created in hackney_request.erl.

Thanks,

Argument Error on :ets.lookup in ReleaseReader

Hello,

I'm seeing these regularly in CI:

     ** (ArgumentError) argument error
     stacktrace:
       (stdlib) :ets.lookup(:tzdata_rel_2019a, :zone_and_link_list)
       (tzdata) lib/tzdata/release_reader.ex:16: Tzdata.ReleaseReader.simple_lookup/1
       (tzdata) lib/tzdata/release_reader.ex:9: Tzdata.ReleaseReader.zone_and_link_list/0
       (tzdata) lib/tzdata.ex:61: Tzdata.zone_exists?/1
       (timex) lib/timezone/timezone.ex:358: Timex.Timezone.resolve/3
       (timex) lib/timezone/timezone.ex:526: Timex.Timezone.convert/2

Versions:

Erlang/OTP 21 [erts-10.3.5.5] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe]
Interactive Elixir (1.8.2) - press Ctrl+C to exit (type h() ENTER for help)
tzdata version "1.0.1"

GenServer :tzdata_release_updater terminating

20:21:02.252 [error] GenServer :tzdata_release_updater terminating
** (FunctionClauseError) no function clause matching in Tzdata.Util.first_matching_weekday_in_month/4
    (tzdata) lib/tzdata/util.ex:73: Tzdata.Util.first_matching_weekday_in_month(1932, 4, 7, [])
    (tzdata) lib/tzdata/util.ex:329: Tzdata.Util.time_for_rule/2
    (tzdata) lib/tzdata/period_builder.ex:161: Tzdata.PeriodBuilder.calc_periods_for_year/9
    (tzdata) lib/tzdata/period_builder.ex:180: Tzdata.PeriodBuilder.calc_periods_for_year/9
    (tzdata) lib/tzdata/period_builder.ex:185: Tzdata.PeriodBuilder.calc_periods_for_year/9
    (tzdata) lib/tzdata/period_builder.ex:180: Tzdata.PeriodBuilder.calc_periods_for_year/9
    (tzdata) lib/tzdata/period_builder.ex:185: Tzdata.PeriodBuilder.calc_periods_for_year/9
    (tzdata) lib/tzdata/period_builder.ex:180: Tzdata.PeriodBuilder.calc_periods_for_year/9
    (tzdata) lib/tzdata/period_builder.ex:185: Tzdata.PeriodBuilder.calc_periods_for_year/9
    (tzdata) lib/tzdata/period_builder.ex:180: Tzdata.PeriodBuilder.calc_periods_for_year/9
    (tzdata) lib/tzdata/period_builder.ex:185: Tzdata.PeriodBuilder.calc_periods_for_year/9
    (tzdata) lib/tzdata/period_builder.ex:180: Tzdata.PeriodBuilder.calc_periods_for_year/9
    (tzdata) lib/tzdata/period_builder.ex:185: Tzdata.PeriodBuilder.calc_periods_for_year/9
    (tzdata) lib/tzdata/period_builder.ex:180: Tzdata.PeriodBuilder.calc_periods_for_year/9
    (tzdata) lib/tzdata/period_builder.ex:185: Tzdata.PeriodBuilder.calc_periods_for_year/9
    (tzdata) lib/tzdata/period_builder.ex:180: Tzdata.PeriodBuilder.calc_periods_for_year/9
    (tzdata) lib/tzdata/period_builder.ex:185: Tzdata.PeriodBuilder.calc_periods_for_year/9
    (tzdata) lib/tzdata/period_builder.ex:180: Tzdata.PeriodBuilder.calc_periods_for_year/9
    (tzdata) lib/tzdata/period_builder.ex:185: Tzdata.PeriodBuilder.calc_periods_for_year/9
    (tzdata) lib/tzdata/period_builder.ex:180: Tzdata.PeriodBuilder.calc_periods_for_year/9
Last message: :check_if_time_to_update

This might just be a weird blip on AWS. Is anyone seeing this on other infrastructure as well?

Elixir 1.4.0-rc.1 errors on startup

Seeing this in the console (1.3.3 does not have this issue)

Elixir 1.4.0-rc.1

Interactive Elixir (1.4.0-rc.1) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> [error] Tzdata.ReleaseUpdater :tzdata_release_updater received unexpected message in handle_info/2: {#Reference<0.0.1.1369>,
 %Task{owner: #PID<0.310.0>, pid: #PID<0.375.0>, ref: #Reference<0.0.1.1585>}}

[error] Tzdata.ReleaseUpdater :tzdata_release_updater received unexpected message in handle_info/2: {:DOWN, #Reference<0.0.1.1369>, :process, #PID<0.310.0>, :normal}

Elixir 1.3.3

Interactive Elixir (1.3.3) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)>

Both run on the same project, using version 0.5.9

:tzdata_release_updater terminating, argument error

I'm on elixir 1.2.2, my deps are:

defp deps do
  [
    {:amqp, ">= 0.1.4"},
    {:ecto, "~> 1.1"},
    {:mariaex, "~> 0.6"},
    {:ex_statsd, ">= 0.5.1"},
    {:exrm, "~> 1.0"},
    {:poison, "~> 1.0"},
    {:credo, "~> 0.3", only: [:dev, :test]},
    {:dialyxir, "~> 0.3", only: [:dev]},
    {:timex, "~> 2.0"},
    {:timex_ecto, "~> 1.0"},
    {:httpoison, "~> 0.8.3"}
  ]
end

When I run the project (for example with iex -S mix) I get this after some seconds:

12:48:10.781 [error] Task #PID<0.3269.0> started from :tzdata_release_updater terminating
** (ArgumentError) argument error
    :erlang.hd([])
    (tzdata) lib/tzdata/data_loader.ex:62: Tzdata.DataLoader.do_latest_remote_poll_date/1
    (tzdata) lib/tzdata/data_loader.ex:74: Tzdata.DataLoader.days_since_last_remote_poll/0
    (tzdata) lib/tzdata/release_updater.ex:18: Tzdata.ReleaseUpdater.check_if_time_to_update/0
    (elixir) lib/task/supervised.ex:89: Task.Supervised.do_apply/2
    (elixir) lib/task/supervised.ex:40: Task.Supervised.reply/5
    (stdlib) proc_lib.erl:240: :proc_lib.init_p_do_apply/3
Function: #Function<1.97472105/0 in Tzdata.ReleaseUpdater.init/1>
    Args: []

Issues when running a release on a read-only filesystem

Hi,

recently I discovered a series of crashes related to tzdata, as I am running my release from a read-only filesystem.

=CRASH REPORT==== 21-Dec-2017::09:20:17 ===
  crasher:
    initial call: Elixir.Tzdata.ReleaseUpdater:init/1
    pid: <0.28190.6>
    registered_name: tzdata_release_updater
    exception error: #{'__exception__' => true,
                       '__struct__' => 'Elixir.File.Error',
                       action => <<"write to file">>,
                       path =>
                           <<"/opt/app/lib/tzdata-0.5.14/priv/latest_remote_poll.txt">>,
                       reason => eacces}
      in function  'Elixir.File':'write!'/3 (lib/file.ex, line 831)
      in call from 'Elixir.Tzdata.DataLoader':last_modified_of_latest_available/1 (lib/tzdata/data_loader.ex, line 53)
      in call from 'Elixir.Tzdata.ReleaseUpdater':'loaded_tzdata_matches_remote_last_modified?'/0 (lib/tzdata/release_updater.ex, line 79)
      in call from 'Elixir.Tzdata.ReleaseUpdater':poll_for_update/0 (lib/tzdata/release_updater.ex, line 40)
      in call from 'Elixir.Tzdata.ReleaseUpdater':handle_info/2 (lib/tzdata/release_updater.ex, line 17)
      in call from gen_server:try_dispatch/4 (gen_server.erl, line 616)
      in call from gen_server:handle_msg/6 (gen_server.erl, line 686)
    ancestors: [<0.1494.0>,<0.1493.0>]
    message_queue_len: 0
    messages: []
    links: [<0.1494.0>]
    dictionary: []
    trap_exit: false
    status: running
    heap_size: 987
    stack_size: 27
    reductions: 1634

Is there another way to make use of tzdata, maybe pointing it to a writable directory?

Kind regards,

Lukas Rieder

data_loader.ex does not use If-Modified-Since

Hi,

I'm writing to suggest complementing or replacing the existing Content-Length checks in data_loader.ex with an If-Modified-Since header, commonly used by web browsers to avoid the delay of a download operation.

% nc -C www.iana.org 80
GET /time-zones/repository/tzdata-latest.tar.gz HTTP/1.1
Host: www.iana.org
User-Agent: https://github.com/lau/tzdata
If-Modified-Since: Tue, 28 Feb 2017 21:18:44 GMT

HTTP/1.1 304 Not Modified
Date: Thu, 09 Mar 2017 04:33:21 GMT
Last-Modified: Tue, 28 Feb 2017 21:18:44 GMT

I would like to have attached a patch, but I'm not familiar enough with Erlang/Hackney to quickly create one to use this If-Modified-Since method. However, I'm interested enough in seeing this feature exist I'd hack up a diff after a day's research if that's what I have to do.

I hope this suggestion can perhaps simplify the operation: Instead of a combination of GETs and HEADs the fetch could become just GETs, with the difference between an unmodified GET or modified GET revealed by the empty 304 or normal 200 response.

Thanks,

Tzdata.ReleaseUpdater argument error

Hello,

Erlang/OTP 22 [erts-10.5] [source] [64-bit] [smp:16:16] [ds:16:16:10] [async-threads:1]

IEx 1.9.4 (compiled with Erlang/OTP 22)
{
    "hackney": {:hex, :hackney, "1.15.2", "07e33c794f8f8964ee86cebec1a8ed88db5070e52e904b8f12209773c1036085"},
    "timex": {:hex, :timex, "3.6.1", "efdf56d0e67a6b956cc57774353b0329c8ab7726766a11547e529357ffdc1d56"},
    "tzdata": {:hex, :tzdata, "1.0.2", "6c4242c93332b8590a7979eaf5e11e77d971e579805c44931207e32aa6ad3db1"}
}

I've been getting an error every time my project tries to update the timezone database, for a few weeks now.

** (ArgumentError) argument error
    (stdlib) :ets.lookup_element(:hackney_config, :mod_metrics, 2)
    /proj/deps/hackney/src/hackney_metrics.erl:26: :hackney_metrics.get_engine/0
    /proj/deps/hackney/src/hackney_connect.erl:78: :hackney_connect.create_connection/5
    /proj/deps/hackney/src/hackney_connect.erl:47: :hackney_connect.connect/5
    /proj/deps/hackney/src/hackney.erl:333: :hackney.request/5
    (tzdata) lib/tzdata/http_client/hackney.ex:17: Tzdata.HTTPClient.Hackney.head/3
    (tzdata) lib/tzdata/data_loader.ex:46: Tzdata.DataLoader.last_modified_of_latest_available/1
    (tzdata) lib/tzdata/release_updater.ex:81: Tzdata.ReleaseUpdater.loaded_tzdata_matches_remote_last_modified?/0
    (tzdata) lib/tzdata/release_updater.ex:42: Tzdata.ReleaseUpdater.poll_for_update/0

I've run into a dead end debugging this as the Tzdata.HTTPClient.Hackney module uses the callback system I'm not familiar with.

I also don't see any similar issues created, so I'm thinking this is some sort of configuration error on my part. Do you perhaps have an idea why this is erroring?

Would it be possible to remove the dependency on hackney?

First: thanks for maintaining tzdata!
Background story:

I was playing today with SchedEx Empex NYC 2018 Talk + Github and noticed that tzdata pulls quite some transient dependencies.

$ mix app.tree
schedextest
├── elixir
├── logger
│   └── elixir
├── cortex
│   ├── elixir
│   ├── logger
│   └── file_system
│       ├── elixir
│       └── logger
└── sched_ex
    ├── elixir
    ├── crontab
    │   ├── elixir
    │   └── logger
    ├── logger
    └── timex
        ├── elixir
        ├── logger
        ├── tzdata
        │   ├── elixir
        │   ├── hackney
        │   │   ├── crypto
        │   │   ├── asn1
        │   │   ├── public_key
        │   │   │   ├── asn1
        │   │   │   └── crypto
        │   │   ├── ssl
        │   │   │   ├── crypto
        │   │   │   └── public_key
        │   │   ├── idna
        │   │   │   └── unicode_util_compat
        │   │   ├── mimerl
        │   │   ├── certifi
        │   │   ├── ssl_verify_fun
        │   │   │   └── ssl
        │   │   └── metrics
        │   └── logger
        ├── gettext
        │   ├── elixir
        │   └── logger
        └── combine
            └── elixir

The only place where hackney is needed is in this module: https://github.com/lau/tzdata/blob/06da3182cc948902bc42a3cec86552744382c229/lib/tzdata/data_loader.ex doing a get / head requests. Nothings fancy and also not performance-critical because it only has to download 300k file once in a while.

One option would be to use something like https://github.com/alexandrubagu/simplehttp, the other would be to include (embed / vendor-in) a small module that wraps :httpc.request. That way tzdata would be independent of any http client implementations by using the always present :httpc implementation.

I understand that this does not look like high prio issue, yet considering the popularity of timex and other libraries depending on tzdata it might be sensible to shed some of the dependencies longterm to make including tzdata as painless as possible.

Here are some numbers to make it more visual:

https://hex.pm/packages?search=depends%3Acalendar -> 29 dependencies of calender, guardian and quantum being the most popular.

https://hex.pm/packages?search=depends%3Atimex -> 209 dependencies of timexwith a lot of popular packages...

Hope this will get proper consideration and have a nice day!

ets file is missing and autoupdate :disabled ==> :nxdomain error

Using v0.5.7, in a compiled release, I find that tzdata errors out with :nxdomain when autoupdate is set to :disabled and the ets file is missing.

The error stacktrace (https://files.slack.com/files-pri/T08E7VBSA-F20JFDHT6/pasted_image_at_2016_08_11_03_28_pm.png
) makes me think it is trying to make a network connection (the test VM is "disconnected", and the error says :nxdomain).

  • Should not connect to the network if autoupdate = :disabled
  • Should have a better, clearer error msg

Support disabling auto-update

We'd like to have reproducible builds, so having tzdata opportunistically download new versions of the database is something I'd like to be able to disable. Ideally I'd also like to make the hackney dependency optional.

Question: why were the functions related to `zone1970.tab` data removed (module `TableData`)?

I found some useful functions using the zone1970.tab data, that allow for example to retrieve the timezone names based on a country code. This seems useful for example for helping a user to pick a timezone based on a country input.

The module providing such functions (TableData) was found in the 0.1.x versions but has since then been removed.
69081f3
07efc3e

I was just curious to know why this has been removed.

compile issue

==> tzdata
Compiled lib/tzdata/parser_organizer.ex
Compiled lib/tzdata/release_parser.ex
Compiled lib/tzdata/util.ex
Compiled lib/tzdata/table_parser.ex
Compiled lib/tzdata/parser.ex
Compiled lib/tzdata/table_data.ex
Compiled lib/tzdata/leap_sec_parser.ex
Compiled lib/tzdata/basic_data.ex
Compiled lib/tzdata/period_builder.ex
Compiled lib/tzdata/far_future_dynamic_periods.ex
*** stack smashing detected ***: /usr/local/lib/erlang/erts-6.2/bin/beam terminated
Segmentation fault (core dumped)

Argument error in Tzdata.ReleaseReader

Hey @lau, was updating Timex's tzdata dependency to 0.5.1 and hit the following error when calling Tzdata.canonical_zone_list:

Erlang/OTP 18 [erts-7.0.2] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]

Interactive Elixir (1.0.5) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> Tzdata.canonical_zone_list
** (ArgumentError) argument error
    (stdlib) :ets.lookup(:tzdata_current_release, :release_version)
    (tzdata) lib/tzdata/release_reader.ex:41: Tzdata.ReleaseReader.current_release_from_table/0
    (tzdata) lib/tzdata/release_reader.ex:13: Tzdata.ReleaseReader.simple_lookup/1
    (tzdata) lib/tzdata/release_reader.ex:5: Tzdata.ReleaseReader.zone_list/0
iex(1)>

unable to run when from escript

Hi, experimenting with various Elixir time libraries - https://github.com/binarytemple/poc_elixir_calendars/tree/escript_broken

Everything works fine in IEX session. But when escripted there is a crash at startup within the Tzdata application.

I build like so:

mix do deps.compile, escript.build && ./poc_elixir_calendars

The error (formatted) is the following:

{:error, {:shutdown,
    {:failed_to_start_child, Tzdata.EtsHolder,
     {%ArgumentError{message: "unknown application: :tzdata"},
    [
    {Application, :app_dir, 1, [file: 'lib/application.ex', line: 372]},
    {Application, :app_dir, 2, [file: 'lib/application.ex', line: 381]},
    {Tzdata.EtsHolder, :release_dir, 0, [file: 'lib/tzdata/ets_holder.ex', line: 86]},
    {Tzdata.EtsHolder, :make_sure_a_release_dir_exists, 0,
     [file: 'lib/tzdata/ets_holder.ex', line: 70]},
    {Tzdata.EtsHolder, :make_sure_a_release_is_on_file, 0,
     [file: 'lib/tzdata/ets_holder.ex', line: 64]},
    {Tzdata.EtsHolder, :init, 1, [file: 'lib/tzdata/ets_holder.ex', line: 10]},
    {:gen_server, :init_it, 6, [file: 'gen_server.erl', line: 328]},
    {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 240]
    }
    ]}}}}

The escript contains all the Tzdata files, including the ETS dump, '2016c.ets':

 % zipinfo poc_elixir_calendars | egrep -i '(ets|tz)'
-rw----     2.0 fat     1079 b- defN 31-Jul-16 21:14 tzdata.app
-rw----     2.0 fat    11516 b- defN 31-Jul-16 21:14 Elixir.Calendar.DateTime.TzPeriod.beam
-rw----     2.0 fat     5232 b- defN 31-Jul-16 21:14 Elixir.Tzdata.ReleaseUpdater.beam
-rw----     2.0 fat     9372 b- defN 31-Jul-16 21:14 Elixir.Tzdata.DataLoader.beam
-rw----     2.0 fat     3504 b- defN 31-Jul-16 21:14 Elixir.Tzdata.TableParser.beam
-rw----     2.0 fat  3397782 b- defN 31-Jul-16 21:14 2016c.ets
-rw----     2.0 fat     9932 b- defN 31-Jul-16 21:14 Elixir.Tzdata.Parser.beam
-rw----     2.0 fat    12232 b- defN 31-Jul-16 21:14 Elixir.Tzdata.beam
-rw----     2.0 fat     8292 b- defN 31-Jul-16 21:14 Elixir.Tzdata.DataBuilder.beam
-rw----     2.0 fat     5060 b- defN 31-Jul-16 21:14 Elixir.Tzdata.ReleaseReader.beam
-rw----     2.0 fat     3196 b- defN 31-Jul-16 21:14 Elixir.Tzdata.BasicDataMap.beam
-rw----     2.0 fat     6116 b- defN 31-Jul-16 21:14 Elixir.Tzdata.ParserOrganizer.beam
-rw----     2.0 fat     7640 b- defN 31-Jul-16 21:14 Elixir.Tzdata.EtsHolder.beam
-rw----     2.0 fat    19732 b- defN 31-Jul-16 21:14 Elixir.Tzdata.Util.beam
-rw----     2.0 fat     9368 b- defN 31-Jul-16 21:14 Elixir.Tzdata.FarFutureDynamicPeriods.beam
-rw----     2.0 fat     5204 b- defN 31-Jul-16 21:14 Elixir.Tzdata.LeapSecParser.beam
-rw----     2.0 fat     2236 b- defN 31-Jul-16 21:14 Elixir.Tzdata.App.beam
-rw----     2.0 fat     1088 b- defN 31-Jul-16 21:14 Elixir.Tzdata.TableData.beam
-rw----     2.0 fat    12828 b- defN 31-Jul-16 21:14 Elixir.Tzdata.PeriodBuilder.beam

Any suggestions?

UndefinedFunctionError or wrong gap when date-time hits exactly the start of a gap

Hello, if the date-time hits exactly the start of a gap the following values are returned:

iex(11)> Tzdata.TimeZoneDatabase.time_zone_periods_from_wall_datetime(~N[2019-03-10 02:00:00], "America/Goose_Bay")
{:gap,
 {%{
    from_wall: ~N[2018-03-11 03:00:00],
    std_offset: 3600,
    until_wall: ~N[2018-11-04 02:00:00],
    utc_offset: -14400,
    zone_abbr: "ADT"
  }, ~N[2018-11-04 02:00:00]},
 {%{
    from_wall: ~N[2019-03-10 03:00:00],
    std_offset: 3600,
    until_wall: ~N[2019-11-03 02:00:00],
    utc_offset: -14400,
    zone_abbr: "ADT"
  }, ~N[2019-03-10 03:00:00]}}
iex(12)> Tzdata.TimeZoneDatabase.time_zone_periods_from_wall_datetime(~N[1884-01-01 00:00:00], "America/Goose_Bay")
** (UndefinedFunctionError) function nil.utc_off/0 is undefined. If you are using the dot syntax, such as map.field or module.function, make sure the left side of the dot is an atom or a map
    nil.utc_off()
    (tzdata) lib/tzdata/time_zone_database.ex:97: Tzdata.TimeZoneDatabase.old_tz_period_to_new/1
    (tzdata) lib/tzdata/time_zone_database.ex:67: Tzdata.TimeZoneDatabase.gap_for_time_zone/2
iex(12)>

One second later everything is ok:

iex(14)> Tzdata.TimeZoneDatabase.time_zone_periods_from_wall_datetime(~N[2019-03-10 02:00:01], "America/Goose_Bay")
{:gap,
 {%{
    from_wall: ~N[2018-11-04 01:00:00],
    std_offset: 0,
    until_wall: ~N[2019-03-10 02:00:00],
    utc_offset: -14400,
    zone_abbr: "AST"
  }, ~N[2019-03-10 02:00:00]},
 {%{
    from_wall: ~N[2019-03-10 03:00:00],
    std_offset: 3600,
    until_wall: ~N[2019-11-03 02:00:00],
    utc_offset: -14400,
    zone_abbr: "ADT"
  }, ~N[2019-03-10 03:00:00]}}
iex(15)> Tzdata.TimeZoneDatabase.time_zone_periods_from_wall_datetime(~N[1884-01-01 00:00:01], "America/Goose_Bay")
{:gap,
 {%{
    from_wall: :min,
    std_offset: 0,
    until_wall: ~N[1884-01-01 00:00:00],
    utc_offset: -14500,
    zone_abbr: "LMT"
  }, ~N[1884-01-01 00:00:00]},
 {%{
    from_wall: ~N[1884-01-01 00:30:48],
    std_offset: 0,
    until_wall: ~N[1918-01-01 00:00:00],
    utc_offset: -12652,
    zone_abbr: "NST"
  }, ~N[1884-01-01 00:30:48]}}
iex(16)>
iex(1)> Tzdata.tzdata_version
"2019c"
$> mix hex.outdated tzdata
Current version 1.0.2 of dependency is up to date!

Argument error on update

We've just started getting this crash when tzdata tries to do an update of its data:

  crasher:
    initial call: Elixir.Tzdata.ReleaseUpdater:init/1
    pid: <0.2305.0>
    registered_name: tzdata_release_updater
    exception exit: {
{badarg,[{erlang,hd,[[]],[]},
{'Elixir.Tzdata.DataLoader',content_length_from_headers,1,[{file,"lib/tzdata/data_loader.ex"},{line,29}]},{'Elixir.Tzdata.DataLoader',do_latest_file_size,1,[{file,"lib/tzdata/data_loader.ex"},{line,51}]},
{'Elixir.Tzdata.ReleaseUpdater','loaded_tzdata_matches_iana_file_size?',0,[{file,"lib/tzdata/release_updater.ex"},{line,48}]},
{'Elixir.Tzdata.ReleaseUpdater',poll_for_update,0,[{file,"lib/tzdata/release_updater.ex"},{line,36}]},
{'Elixir.Tzdata.ReleaseUpdater',handle_info,2,[{file,"lib/tzdata/release_updater.ex"},{line,17}]},
{gen_server,try_dispatch,4,[{file,"gen_server.erl"},{line,601}]},
{gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,667}]}]},
[{gen_server,terminate,7,[{file,"gen_server.erl"},{line,812}]},
{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,247}]}]}

Best as I can tell, the HEAD data it's pulling no longer contains the Content-Length field. Indeed a quick test seems to bear this out:

$ curl --head https://www.iana.org/time-zones/repository/tzdata-latest.tar.gz
HTTP/1.1 200 OK
Date: Tue, 07 Mar 2017 00:30:29 GMT
X-Frame-Options: SAMEORIGIN
Content-Security-Policy: upgrade-insecure-requests
Last-Modified: Tue, 28 Feb 2017 21:18:44 GMT
Vary: Accept-Encoding
content-type: application/x-gzip
content-encoding: identity
Cache-Control: public, max-age=3600
Server: Apache
X-Cache-Host: www-varnish.iana.org
X-Cache-Hits: 1413
Accept-Ranges: bytes
Connection: keep-alive
Strict-Transport-Security: max-age=48211200

But of course I could be misreading the code.

Edit: We're running 0.5.10

tzdata_release_updater runs during compilation

I got this error after cleaning my deps and running mix deps.get and then iex -S mix:

18:16:19.924 [error] Task #PID<0.786.0> started from :tzdata_release_updater terminating
** (File.Error) could not stream priv/tmp_downloads/302817//pacificnew: no such file or directory
    (elixir) lib/file/stream.ex:77: anonymous fn/2 in Enumerable.File.Stream.reduce/3
    (elixir) lib/stream.ex:1084: anonymous fn/5 in Stream.resource/3
    (elixir) lib/stream.ex:1247: Enumerable.Stream.do_each/4
    (elixir) lib/enum.ex:1477: Enum.reduce/3
    (elixir) lib/enum.ex:2248: Enum.to_list/1
    (tzdata) lib/tzdata/parser.ex:16: Tzdata.Parser.process_file/1
    (tzdata) lib/tzdata/basic_data_map.ex:8: anonymous fn/2 in Tzdata.BasicDataMap.from_files_in_dir/1
    (elixir) lib/enum.ex:1088: Enum."-map/2-lists^map/1-0-"/2
Function: #Function<0.19695994/0 in Tzdata.ReleaseUpdater.init/1>
    Args: []

This was surprising and I don't think it is appropriate to run the updater during the compilation step. It should only ever run when the main app is running.

This is version 0.5.2 of tzdata.

Add possibility to use tzdata provided by OS

Making it more operations compliant, and allow to update all tzdata in one run.
Add possibility to read tzdata from OS (which is on every Linux already installed and updated).

Make it sense?

Make not auto-updating the default

I think it's an utterly bad idea to have libraries auto-update. Frankly, I hate the concept. You change the behavior on production, you are pulling random stuff from the internet into production systems, it may or may not slow down startup by a random amount; it has all sorts of security implications I simply don't want to think about.

Please make the default to disable auto update; I'm fine if people want this (although I can think of exactly zero reasons why), but libraries should have secure defaults.

Configurable download_url

Would you be opposed to a pull request moving the downlad_url value to config.exs?

We use this behind a firewall and can only get database updates with tzdata releases.

:tzdata_release_updater terminating & argument error

I see following error whenever I do mix phoenix.server at the start of my day

[error] GenServer :tzdata_release_updater terminating
** (ArgumentError) argument error
    :erlang.hd([])
    (tzdata) lib/tzdata/data_loader.ex:29: Tzdata.DataLoader.content_length_from_headers/1
    (tzdata) lib/tzdata/data_loader.ex:51: Tzdata.DataLoader.do_latest_file_size/1
    (tzdata) lib/tzdata/release_updater.ex:48: Tzdata.ReleaseUpdater.loaded_tzdata_matches_iana_file_size?/0
    (tzdata) lib/tzdata/release_updater.ex:36: Tzdata.ReleaseUpdater.poll_for_update/0
    (tzdata) lib/tzdata/release_updater.ex:17: Tzdata.ReleaseUpdater.handle_info/2
    (stdlib) gen_server.erl:616: :gen_server.try_dispatch/4
    (stdlib) gen_server.erl:686: :gen_server.handle_msg/6
    (stdlib) proc_lib.erl:247: :proc_lib.init_p_do_apply/3
Last message: :check_if_time_to_update
State: []

Looks like some issue fetching time zone data or some other error?

Negative leap seconds

This might be more theoretical than practical, but as I understand it there could be negative leap seconds (that is, a second less than normal) and not just extra leap seconds. It's never happened so far, but the UTC standard seems to be built upon than possibility.

How would tzdata handle a negative leap second? leap_seconds/0 only states when a leap second occurs, assuming (explicitly in the function documentation) that it's extra (positive) leap seconds.

Library making http requests, without possibility to disabling it

Library doing some http checks, I think that it is not good in all environments (for example because of security reasons) to make some wild http requests in a library, which doesn't seem to need to do it (it is not an API to extern data).

Would be nice to add some configuration option, like: check_new_releases: true | false or outsource the supervisor for release updates, that if somebody really want to update it regular, should release_updater in its own supervisor tree. What do you think about it?

GenServer Tzdata.EtsHolder terminating when update

I got a Tzdata.EtsHolder error when updating tzdata. It seems downloading succeeded, but parsing failed.

  • Elixir 1.7
  • tzdata 0.5.19

Log is a bit long because we use Sentry logger.

Interactive Elixir (1.7.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> 
03:57:49.652 [debug] Tzdata polling for update.
 
03:57:50.863 [info]  tzdata release in place is from a file last modified Mon, 31 Dec 2018 01:25:12 GMT. Release file on server was last modified Tue, 26 Mar 2019 05:40:14 GMT.
2019-03-27T12:57:50.864 [info] tzdata release in place is from a file last modified Mon, 31 Dec 2018 01:25:12 GMT. Release file on server was last modified Tue, 26 Mar 2019 05:40:14 GMT.

03:57:50.869 [debug] Tzdata downloading new data from https://data.iana.org/time-zones/tzdata-latest.tar.gz
 
03:57:52.029 [debug] Tzdata data downloaded. Release version 20198.
 
03:57:53.020 [error] GenServer Tzdata.EtsHolder terminating
** (MatchError) no match of right hand side value: {:error, :cannot_create_table}
    (tzdata) lib/tzdata/ets_holder.ex:59: Tzdata.EtsHolder.load_ets_table/1
    (tzdata) lib/tzdata/ets_holder.ex:52: Tzdata.EtsHolder.load_release/0
    (tzdata) lib/tzdata/ets_holder.ex:23: Tzdata.EtsHolder.handle_cast/2
    (stdlib) gen_server.erl:637: :gen_server.try_dispatch/4
    (stdlib) gen_server.erl:711: :gen_server.handle_msg/6
    (stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3
Last message: {:"$gen_cast", :new_release_has_been_downloaded}
State: "2018i"
2019-03-27T12:57:53.118 [error] GenServer Tzdata.EtsHolder terminating
** (MatchError) no match of right hand side value: {:error, :cannot_create_table}
    (tzdata) lib/tzdata/ets_holder.ex:59: Tzdata.EtsHolder.load_ets_table/1
    (tzdata) lib/tzdata/ets_holder.ex:52: Tzdata.EtsHolder.load_release/0
    (tzdata) lib/tzdata/ets_holder.ex:23: Tzdata.EtsHolder.handle_cast/2
    (stdlib) gen_server.erl:637: :gen_server.try_dispatch/4
    (stdlib) gen_server.erl:711: :gen_server.handle_msg/6
    (stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3
Last message: {:"$gen_cast", :new_release_has_been_downloaded}
State: "2018i"

03:57:53.117 [error] :gen_event handler Sentry.LoggerBackend installed in Logger terminating
** (FunctionClauseError) no function clause matching in URI.parse/1
    (elixir) lib/uri.ex:414: URI.parse(nil)
    (sentry) lib/sentry/client.ex:226: Sentry.Client.get_dsn/0
    (sentry) lib/sentry/client.ex:329: Sentry.Client.get_headers_and_endpoint/0
    (sentry) lib/sentry/client.ex:92: Sentry.Client.do_send_event/3
    (sentry) lib/sentry/logger_backend.ex:38: Sentry.LoggerBackend.handle_event/2
    (stdlib) gen_event.erl:577: :gen_event.server_update/4
    (stdlib) gen_event.erl:559: :gen_event.server_notify/4
    (stdlib) gen_event.erl:300: :gen_event.handle_msg/6
Last message: {:error, #PID<0.327.0>, {Logger, [["GenServer ", "Tzdata.EtsHolder", " terminating", [[10 | "** (MatchError) no match of right hand side value: {:error, :cannot_create_table}"], ["\n    " | "(tzdata) lib/tzdata/ets_holder.ex:59: Tzdata.EtsHolder.load_ets_table/1"], ["\n    " | "(tzdata) lib/tzdata/ets_holder.ex:52: Tzdata.EtsHolder.load_release/0"], ["\n    " | "(tzdata) lib/tzdata/ets_holder.ex:23: Tzdata.EtsHolder.handle_cast/2"], ["\n    " | "(stdlib) gen_server.erl:637: :gen_server.try_dispatch/4"], ["\n    " | "(stdlib) gen_server.erl:711: :gen_server.handle_msg/6"], ["\n    " | "(stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3"]], "\nLast message", [], ": ", "{:\"$gen_cast\", :new_release_has_been_downloaded}"], "\nState: ", "\"2018i\""], {{2019, 3, 27}, {3, 57, 53, 20}}, [registered_name: Tzdata.EtsHolder, crash_reason: {%MatchError{term: {:error, :cannot_create_table}}, [{Tzdata.EtsHolder, :load_ets_table, 1, [file: 'lib/tzdata/ets_holder.ex', line: 59]}, {Tzdata.EtsHolder, :load_release, 0, [file: 'lib/tzdata/ets_holder.ex', line: 52]}, {Tzdata.EtsHolder, :handle_cast, 2, [file: 'lib/tzdata/ets_holder.ex', line: 23]}, {:gen_server, :try_dispatch, 4, [file: 'gen_server.erl', line: 637]}, {:gen_server, :handle_msg, 6, [file: 'gen_server.erl', line: 711]}, {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 249]}]}, function: "error_info/7", module: :gen_server, line: 888, file: "gen_server.erl", pid: #PID<0.330.0>]}}
State: %Sentry.LoggerBackend{level: nil}
2019-03-27T12:57:53.118 [error] :gen_event handler Sentry.LoggerBackend installed in Logger terminating
** (FunctionClauseError) no function clause matching in URI.parse/1
    (elixir) lib/uri.ex:414: URI.parse(nil)
    (sentry) lib/sentry/client.ex:226: Sentry.Client.get_dsn/0
    (sentry) lib/sentry/client.ex:329: Sentry.Client.get_headers_and_endpoint/0
    (sentry) lib/sentry/client.ex:92: Sentry.Client.do_send_event/3
    (sentry) lib/sentry/logger_backend.ex:38: Sentry.LoggerBackend.handle_event/2
    (stdlib) gen_event.erl:577: :gen_event.server_update/4
    (stdlib) gen_event.erl:559: :gen_event.server_notify/4
    (stdlib) gen_event.erl:300: :gen_event.handle_msg/6
Last message: {:error, #PID<0.327.0>, {Logger, [["GenServer ", "Tzdata.EtsHolder", " terminating", [[10 | "** (MatchError) no match of right hand side value: {:error, :cannot_create_table}"], ["\n    " | "(tzdata) lib/tzdata/ets_holder.ex:59: Tzdata.EtsHolder.load_ets_table/1"], ["\n    " | "(tzdata) lib/tzdata/ets_holder.ex:52: Tzdata.EtsHolder.load_release/0"], ["\n    " | "(tzdata) lib/tzdata/ets_holder.ex:23: Tzdata.EtsHolder.handle_cast/2"], ["\n    " | "(stdlib) gen_server.erl:637: :gen_server.try_dispatch/4"], ["\n    " | "(stdlib) gen_server.erl:711: :gen_server.handle_msg/6"], ["\n    " | "(stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3"]], "\nLast message", [], ": ", "{:\"$gen_cast\", :new_release_has_been_downloaded}"], "\nState: ", "\"2018i\""], {{2019, 3, 27}, {3, 57, 53, 20}}, [registered_name: Tzdata.EtsHolder, crash_reason: {%MatchError{term: {:error, :cannot_create_table}}, [{Tzdata.EtsHolder, :load_ets_table, 1, [file: 'lib/tzdata/ets_holder.ex', line: 59]}, {Tzdata.EtsHolder, :load_release, 0, [file: 'lib/tzdata/ets_holder.ex', line: 52]}, {Tzdata.EtsHolder, :handle_cast, 2, [file: 'lib/tzdata/ets_holder.ex', line: 23]}, {:gen_server, :try_dispatch, 4, [file: 'gen_server.erl', line: 637]}, {:gen_server, :handle_msg, 6, [file: 'gen_server.erl', line: 711]}, {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 249]}]}, function: "error_info/7", module: :gen_server, line: 888, file: "gen_server.erl", pid: #PID<0.330.0>]}}
State: %Sentry.LoggerBackend{level: nil}

03:57:53.120 [error] GenServer #PID<0.538.0> terminating
** (stop) {:EXIT, {:function_clause, [{URI, :parse, [nil], [file: 'lib/uri.ex', line: 414]}, {Sentry.Client, :get_dsn, 0, [file: 'lib/sentry/client.ex', line: 226]}, {Sentry.Client, :get_headers_and_endpoint, 0, [file: 'lib/sentry/client.ex', line: 329]}, {Sentry.Client, :do_send_event, 3, [file: 'lib/sentry/client.ex', line: 92]}, {Sentry.LoggerBackend, :handle_event, 2, [file: 'lib/sentry/logger_backend.ex', line: 38]}, {:gen_event, :server_update, 4, [file: 'gen_event.erl', line: 577]}, {:gen_event, :server_notify, 4, [file: 'gen_event.erl', line: 559]}, {:gen_event, :handle_msg, 6, [file: 'gen_event.erl', line: 300]}]}}
Last message: {:gen_event_EXIT, Sentry.LoggerBackend, {:EXIT, {:function_clause, [{URI, :parse, [nil], [file: 'lib/uri.ex', line: 414]}, {Sentry.Client, :get_dsn, 0, [file: 'lib/sentry/client.ex', line: 226]}, {Sentry.Client, :get_headers_and_endpoint, 0, [file: 'lib/sentry/client.ex', line: 329]}, {Sentry.Client, :do_send_event, 3, [file: 'lib/sentry/client.ex', line: 92]}, {Sentry.LoggerBackend, :handle_event, 2, [file: 'lib/sentry/logger_backend.ex', line: 38]}, {:gen_event, :server_update, 4, [file: 'gen_event.erl', line: 577]}, {:gen_event, :server_notify, 4, [file: 'gen_event.erl', line: 559]}, {:gen_event, :handle_msg, 6, [file: 'gen_event.erl', line: 300]}]}}}
State: {Logger, Sentry.LoggerBackend}
2019-03-27T12:57:53.121 [error] GenServer #PID<0.538.0> terminating
** (stop) {:EXIT, {:function_clause, [{URI, :parse, [nil], [file: 'lib/uri.ex', line: 414]}, {Sentry.Client, :get_dsn, 0, [file: 'lib/sentry/client.ex', line: 226]}, {Sentry.Client, :get_headers_and_endpoint, 0, [file: 'lib/sentry/client.ex', line: 329]}, {Sentry.Client, :do_send_event, 3, [file: 'lib/sentry/client.ex', line: 92]}, {Sentry.LoggerBackend, :handle_event, 2, [file: 'lib/sentry/logger_backend.ex', line: 38]}, {:gen_event, :server_update, 4, [file: 'gen_event.erl', line: 577]}, {:gen_event, :server_notify, 4, [file: 'gen_event.erl', line: 559]}, {:gen_event, :handle_msg, 6, [file: 'gen_event.erl', line: 300]}]}}
Last message: {:gen_event_EXIT, Sentry.LoggerBackend, {:EXIT, {:function_clause, [{URI, :parse, [nil], [file: 'lib/uri.ex', line: 414]}, {Sentry.Client, :get_dsn, 0, [file: 'lib/sentry/client.ex', line: 226]}, {Sentry.Client, :get_headers_and_endpoint, 0, [file: 'lib/sentry/client.ex', line: 329]}, {Sentry.Client, :do_send_event, 3, [file: 'lib/sentry/client.ex', line: 92]}, {Sentry.LoggerBackend, :handle_event, 2, [file: 'lib/sentry/logger_backend.ex', line: 38]}, {:gen_event, :server_update, 4, [file: 'gen_event.erl', line: 577]}, {:gen_event, :server_notify, 4, [file: 'gen_event.erl', line: 559]}, {:gen_event, :handle_msg, 6, [file: 'gen_event.erl', line: 300]}]}}}
State: {Logger, Sentry.LoggerBackend}

I also try 1.0.0-rc.0 (though on Elixir 1.7) but same error:

Interactive Elixir (1.7.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> 
13:16:46.050 [debug] Tzdata polling for update.
 
13:16:46.772 [info]  tzdata release in place is from a file last modified Mon, 31 Dec 2018 01:25:12 GMT. Release file on server was last modified Tue, 26 Mar 2019 05:40:14 GMT.
 
13:16:46.772 [debug] Tzdata downloading new data from https://data.iana.org/time-zones/tzdata-latest.tar.gz
 
13:16:47.461 [debug] Tzdata data downloaded. Release version 20198.
 
13:16:48.556 [error] GenServer Tzdata.EtsHolder terminating
** (MatchError) no match of right hand side value: {:error, :cannot_create_table}
    (tzdata) lib/tzdata/ets_holder.ex:63: Tzdata.EtsHolder.load_ets_table/1
    (tzdata) lib/tzdata/ets_holder.ex:56: Tzdata.EtsHolder.load_release/0
    (tzdata) lib/tzdata/ets_holder.ex:27: Tzdata.EtsHolder.handle_cast/2
    (stdlib) gen_server.erl:637: :gen_server.try_dispatch/4
    (stdlib) gen_server.erl:711: :gen_server.handle_msg/6
    (stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3
Last message: {:"$gen_cast", :new_release_has_been_downloaded}
State: "2018i"

Location for downloading data is inflexible

Location, where data saved is hardcoded to priv.

Problem is, that: https://github.com/lau/tzdata/blob/master/lib/tzdata/data_loader.ex#L13 based on CWD it creates a priv. For example on releases, it seems, like: release_name/priv/... not in tzdata/priv, but somewhere starting from cwd. That means, on releases, where CWD is changed, it is not really known, where the priv folder should be created.

Possible solutions: explicitly define the download directory in configuration (download_dir: "/tmp/..." ), or use :code.priv_dir for it. I'm against to use priv dir so explicitly for mutable data. Problem is, that it makes impossible to install release on immutable location(at least for a application themself), and configure the whole application to have it mutable data on another storage.

Tzdata polling for update

I observe the below error in my production logs.

[error] GenServer :tzdata_release_updater terminating
** (ArgumentError) argument error
(stdlib) :ets.lookup_element(:hackney_config, :mod_metrics, 2)
/Users/kodepet/Documents/Work/topup/deps/hackney/src/hackney_metrics.erl:26: :hackney_metrics.get_engine/0
/Users/kodepet/Documents/Work/topup/deps/hackney/src/hackney_connect.erl:78: :hackney_connect.create_connection/5
/Users/kodepet/Documents/Work/topup/deps/hackney/src/hackney_connect.erl:47: :hackney_connect.connect/5
/Users/kodepet/Documents/Work/topup/deps/hackney/src/hackney.erl:333: :hackney.request/5
(tzdata) lib/tzdata/http_client/hackney.ex:17: Tzdata.HTTPClient.Hackney.head/3
(tzdata) lib/tzdata/data_loader.ex:46: Tzdata.DataLoader.last_modified_of_latest_available/1
(tzdata) lib/tzdata/release_updater.ex:81: Tzdata.ReleaseUpdater.loaded_tzdata_matches_remote_last_modified?/0
(tzdata) lib/tzdata/release_updater.ex:42: Tzdata.ReleaseUpdater.poll_for_update/0
(tzdata) lib/tzdata/release_updater.ex:19: Tzdata.ReleaseUpdater.handle_info/2
(stdlib) gen_server.erl:637: :gen_server.try_dispatch/4
(stdlib) gen_server.erl:711: :gen_server.handle_msg/6
(stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3
Last message: :check_if_time_to_update
State: []

Error when updating

Using tz_data 0.5.15.

This night I got a couple of error log messages from two different applications deployed on the same host. There was around three hours between the errors and I haven't noticed any other issues with the apps or host.

One of the messages:

[ERROR] <0.2341.0>: GenServer :tzdata_release_updater terminating 
** (File.Error) could not stream "/path/to/app/lib/tzdata-0.5.15/priv/tmp_downloads/339626_44358462//pacificnew": no such file or directory     
(elixir) lib/file/stream.ex:79: anonymous fn/2 in Enumerable.File.Stream.reduce/3     
(elixir) lib/stream.ex:1270: anonymous fn/5 in Stream.resource/3     
(elixir) lib/stream.ex:1433: Enumerable.Stream.do_each/4     (elixir) lib/enum.ex:1841: Enum.reverse/1     
(elixir) lib/enum.ex:2599: Enum.to_list/1     (tzdata) lib/tzdata/parser.ex:16: Tzdata.Parser.process_file/1     
(tzdata) lib/tzdata/basic_data_map.ex:8: anonymous fn/2 in Tzdata.BasicDataMap.from_files_in_dir/1     
(elixir) lib/enum.ex:1273: Enum."-map/2-lists^map/1-0-"/2     (elixir) lib/enum.ex:1273: Enum."-map/2-lists^map/1-0-"/2     
(tzdata) lib/tzdata/basic_data_map.ex:8: Tzdata.BasicDataMap.from_files_in_dir/1     
(tzdata) lib/tzdata/data_builder.ex:32: Tzdata.DataBuilder.do_load_and_save_table/4     
(tzdata) lib/tzdata/release_updater.ex:46: Tzdata.ReleaseUpdater.poll_for_update/0 Last message: :check_if_time_to_update 

The other is similar and can also not find the pacificnew file.

The only other tzdata logs I can find is from around 1 second before the error saying

Tzdata.ReleaseUpdater  [INFO]  <0.2341.0>: tzdata release in place is from a file last modified Mon, 23 Oct 2017 15:19:20 GMT. Release file on server was last modified Tue, 16 Jan 2018 17:43:58 GMT. 

In the latest tzdata from https://www.iana.org/time-zones, the pacificnew is not included, so perhaps it should just be removed from BasicDataMap?

Crashes on new tzinfo?

We're getting this error intermittently and so we're assuming it's part of the autoupdate procedure that's crashing:

** Reason for termination ==
** {badarg,
       [{ets,lookup,[tzdata_current_release,release_version],[]},
        {'Elixir.Tzdata.ReleaseReader',current_release_from_table,0,
            [{file,"lib/tzdata/release_reader.ex"},{line,47}]},
        {'Elixir.Tzdata.ReleaseReader',simple_lookup,1,
            [{file,"lib/tzdata/release_reader.ex"},{line,14}]},
        {'Elixir.Tzdata.ReleaseReader',zone_and_link_list,0,
            [{file,"lib/tzdata/release_reader.ex"},{line,7}]},
        {'Elixir.Tzdata','zone_exists?',1,[{file,"lib/tzdata.ex"},{line,40}]},
        {'Elixir.Timex.Timezone',name_of,1,
            [{file,"lib/timezone/timezone.ex"},{line,142}]},
        {'Elixir.Timex.Timezone',do_get,3,
            [{file,"lib/timezone/timezone.ex"},{line,205}]},
        {'Elixir.Timex.Timezone',convert,2,
            [{file,"lib/timezone/timezone.ex"},{line,458}]}]}
{"Kernel pid terminated",application_controller,"{application_terminated,rtr,shutdown}"}

We have tzdata 0.5.12 and the tzdata version is currently 2017b on my local machine.

[proposal] Split off updater

The discussion about tzdata's unexpected update behaviour came up on Slack again (https://elixir-lang.slack.com/archives/C0AB4A879/p1546084693076000). I think there's a way to have your cake and eat it, too - split off the update logic.

After the split, there'd be two libraries:

  • tzdata which has the pure code, just the time zone access;
  • tzdata_updater which has the side-effecting code that does the updates.

That way, downstream libraries like timex can just depend on the tzdata library and nothing unexpected will happen (nor will maintainers of downstream libraries be forced to make a decision on whether this behaviour is wanted or not - they can't, only the end user can). If someone wants the update behaviour, that is simple enough to accomplish by adding the tzdata_updater dependency as well. No messing around with Mix configs needed.

(needless to say, more than happy to chip in some time to make this happen)

Performance issues

With the "new" ETS-based timezone storage, we have noticed that the performance of the Tzdata.periods_for_time/3 function has dropped quite excessively.

tzdata 0.1.8:

benchmark name           iterations   average time 
Tzdata.periods            100000000   0.07 µs/op
Tzdata.periods_for_time    10000000   0.16 µs/op

tzdata 0.5.10:

benchmark name           iterations   average time 
Tzdata.periods                50000   51.36 µs/op
Tzdata.periods_for_time       20000   78.61 µs/op

Our use case is converting large amounts of dates from the database into DateTime structs (using Timex), and we're now getting performance issues because of this conversion.

I'm wondering what the best solution is here (except for pinning our own tzdata to 0.1.8);
Obviously compiling all timezone data into BEAM bytecode has its downsides (memory usage and not being able to update the tz database in runtime).

cc @nulian @Wijnand

Benchmark code: https://github.com/arjan/tzdata_bench/blob/master/bench/tz_bench.exs

ArgumentError in Tzdata update

Today, We've got this error when startup and sometimes while running:

Elixir.ArgumentError: argument error
  Module "ets", in :ets.new/2
  File "lib/tzdata/data_builder.ex", line 11, in Tzdata.DataBuilder.load_and_save_table/0
  File "lib/tzdata/release_updater.ex", line 41, in Tzdata.ReleaseUpdater.poll_for_update/0
  File "lib/tzdata/release_updater.ex", line 17, in Tzdata.ReleaseUpdater.handle_info/2
  File "gen_server.erl", line 616, in :gen_server.try_dispatch/4
  File "gen_server.erl", line 686, in :gen_server.handle_msg/6
  File "proc_lib.erl", line 247, in :proc_lib.init_p_do_apply/3
  Module "Elixir.Tzdata.ReleaseUpdater", in Tzdata.ReleaseUpdater.init/1

Arguments passed to :ets.new/2

arg0	:tzdata_rel_2017c
arg1	[:set, :named_table]

We use Tzdata 0.5.12 and Timex 3.1.24.

  "timex": {:hex, :timex, "3.1.24", "d198ae9783ac807721cca0c5535384ebdf99da4976be8cefb9665a9262a1e9e3", [:mix], [{:combine, "~> 0.7", [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.12", "1c17b68692c6ba5b6ab15db3d64cc8baa0f182043d5ae9d4b6d35d70af76f67b", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"},

Connections in CLOSE_WAIT

Hi,
I noticed on a number of production servers that there are a number of TCP connection to https://www.iana.org that remain in CLOSE_WAIT. The only code that references www.iana.org seems to be tzdata. Do you have any clue?

COMMAND   PID USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
beam.smp 1424 root   11u  IPv4   18985      0t0  TCP *:35058 (LISTEN)
beam.smp 1424 root   12u  IPv4   18987      0t0  TCP localhost:60553->localhost:epmd (ESTABLISHED)
beam.smp 1424 root   13u  IPv4   18137      0t0  TCP gratwifi.lan:81 (LISTEN)
beam.smp 1424 root   16u  IPv4  422369      0t0  TCP 192.168.1.7:42237->www.iana.org:https (CLOSE_WAIT)
beam.smp 1424 root   17u  IPv4   16152      0t0  UDP *:52241
beam.smp 1424 root   19u  IPv4  723308      0t0  TCP 192.168.1.7:37011->www.iana.org:https (CLOSE_WAIT)
beam.smp 1424 root   20u  IPv4  581191      0t0  TCP 192.168.1.7:60339->www.iana.org:https (CLOSE_WAIT)
beam.smp 1424 root   21u  IPv4 1129389      0t0  TCP 192.168.1.7:54109->www.iana.org:https (CLOSE_WAIT)
beam.smp 1424 root   22u  IPv4  864988      0t0  TCP 192.168.1.7:59174->www.iana.org:https (CLOSE_WAIT)
beam.smp 1424 root   23u  IPv4 1011660      0t0  TCP 192.168.1.7:56804->www.iana.org:https (CLOSE_WAIT)
beam.smp 1424 root   24u  IPv4 1276491      0t0  TCP 192.168.1.7:58875->www.iana.org:https (CLOSE_WAIT)
beam.smp 1424 root   25u  IPv4 1435758      0t0  TCP 192.168.1.7:33240->www.iana.org:https (CLOSE_WAIT)
beam.smp 1424 root   26u  IPv4 1592295      0t0  TCP 192.168.1.7:37590->www.iana.org:https (CLOSE_WAIT)
beam.smp 1424 root   27u  IPv4 1764131      0t0  TCP 192.168.1.7:41133->www.iana.org:https (CLOSE_WAIT)
beam.smp 1424 root   28u  IPv4 2365627      0t0  TCP 192.168.1.7:32983->www.iana.org:https (CLOSE_WAIT)
beam.smp 1424 root   29u  IPv4 1955942      0t0  TCP 192.168.1.7:59567->www.iana.org:https (CLOSE_WAIT)
beam.smp 1424 root   30u  IPv4 2573572      0t0  TCP 192.168.1.7:45931->www.iana.org:https (CLOSE_WAIT)
beam.smp 1424 root   31u  IPv4 2168659      0t0  TCP 192.168.1.7:50945->www.iana.org:https (CLOSE_WAIT)
beam.smp 1424 root   32u  IPv4 2499120      0t0  UDP *:60100
beam.smp 1424 root   33u  IPv4 2979799      0t0  TCP 192.168.1.7:37016->www.iana.org:https (CLOSE_WAIT)
beam.smp 1424 root   34u  IPv4 2785116      0t0  TCP 192.168.1.7:33791->www.iana.org:https (CLOSE_WAIT)
beam.smp 1424 root   35u  IPv4 3183900      0t0  TCP 192.168.1.7:37685->www.iana.org:https (CLOSE_WAIT)
beam.smp 1424 root   36u  IPv4 3352151      0t0  TCP 192.168.1.7:56252->www.iana.org:https (CLOSE_WAIT)
beam.smp 1424 root   37u  IPv4  101022      0t0  TCP 192.168.1.7:59720->www.iana.org:https (CLOSE_WAIT)
beam.smp 1424 root   38u  IPv4  262679      0t0  TCP 192.168.1.7:46152->www.iana.org:https (CLOSE_WAIT)
beam.smp 1424 root   39u  IPv4 3537364      0t0  TCP 192.168.1.7:39599->www.iana.org:https (CLOSE_WAIT)
beam.smp 1424 root   40u  IPv4 3882622      0t0  TCP 192.168.1.7:60647->www.iana.org:https (CLOSE_WAIT)
beam.smp 1424 root   41u  IPv4 3733899      0t0  TCP 192.168.1.7:35346->www.iana.org:https (CLOSE_WAIT)
beam.smp 1424 root   42u  IPv4 4064143      0t0  TCP 192.168.1.7:52116->www.iana.org:https (CLOSE_WAIT)
beam.smp 1424 root   43u  IPv4 4372605      0t0  TCP 192.168.1.7:52828->www.iana.org:https (CLOSE_WAIT)
beam.smp 1424 root   44u  IPv4 4512808      0t0  TCP 192.168.1.7:38491->www.iana.org:https (CLOSE_WAIT)
beam.smp 1424 root   45u  IPv4 4235652      0t0  TCP 192.168.1.7:45662->www.iana.org:https (CLOSE_WAIT)
beam.smp 1424 root   46u  IPv4 4630737      0t0  TCP 192.168.1.7:54971->www.iana.org:https (CLOSE_WAIT)
beam.smp 1424 root   47u  IPv4 4790369      0t0  TCP 192.168.1.7:49358->www.iana.org:https (CLOSE_WAIT)

Function to list possible offsets for a time zone

Most time zone pickers (most oftenly a <select> field) on the web show an offset with the time zone name; and time zones are ordered by offset (see pickers for Windows, Android, Google Calendar, ...).

Currently, I don't see any easy way to get the possible offsets for a time zone.
E.g. for Belgium it would return a list of two elements, +01:00 and +02:00.

Would it be possible to add such feature?

See also discussion on Elixir Forum:
https://elixirforum.com/t/list-of-time-zones-in-select-element/28532

Ability to download fresh tz release during build

Would it be possible to somehow prefetch the fresh tz release during app release assembly?

Maybe some kind of mix task (mix tzdata.download) that would override the version bundled with tzdata package?

The main reason for this is to minimise the possibility of new release starting with old tzdata.

EtsHolder error if process receives a message

I'm running a custom logging backend to mock the logger in test. Instead of log output on stdout, I send messages to the originating process (typically the test process) where I can then assert_received for a particular log message. I've found this mechanism cleaner/easier than capture_log.

But I've hit a problem with tzdata's EtsHolder genserver:

[error] Tzdata.EtsHolder Tzdata.EtsHolder received unexpected message in handle_info/2: {…}

It executes Logger calls, but fails if a message it sent to it.

I'd like to implement a no-op handle_info in EtsHolder. I'm happy to PR it up, but shout out if you hate the idea.

Similar issues, but not quite: #28

(FunctionClauseError) no function clause matching in Keyword.delete_key/3

We encountered an error in one of our apps that uses Timex, which uses Tzdata. Here's the stacktrace:

Elixir.FunctionClauseError: no function clause matching in Keyword.delete_key/3
  File "lib/tzdata/util.ex", line 73, in Tzdata.Util.first_matching_weekday_in_month/4
  File "lib/tzdata/util.ex", line 329, in Tzdata.Util.time_for_rule/2
  File "lib/tzdata/period_builder.ex", line 161, in Tzdata.PeriodBuilder.calc_periods_for_year/9
  File "lib/tzdata/period_builder.ex", line 180, in Tzdata.PeriodBuilder.calc_periods_for_year/9
  File "lib/tzdata/period_builder.ex", line 185, in Tzdata.PeriodBuilder.calc_periods_for_year/9
  File "lib/tzdata/period_builder.ex", line 180, in Tzdata.PeriodBuilder.calc_periods_for_year/9
  File "lib/tzdata/period_builder.ex", line 185, in Tzdata.PeriodBuilder.calc_periods_for_year/9
  File "lib/tzdata/period_builder.ex", line 180, in Tzdata.PeriodBuilder.calc_periods_for_year/9
  Module "Elixir.Tzdata.ReleaseUpdater", in Tzdata.ReleaseUpdater.init/1

The four arguments to Tzdata.Util.first_matching_weekday_in_month/4 are 1932, 4, 7, and [], respectively.

We're using Timex 3.6.1 and Tzdata 1.0.1.

tzdata_release_updater terminating

Hello, I have a Phoenix application that I am running inside a Docker container (bitwalker/alpine-erlang:20.0). I'm using mix_docker for releases.

When I run my application locallyI don't receive this error, but when I run it inside my container this error happens every few seconds or so. I can't find anywhere in my application where I'm using tzdata. I'm having a hard time tracking down what's causing this error. Any help you could provide would be much appreciated.

Error

22:23:52.554 [error] GenServer :tzdata_release_updater terminating
** (File.Error) could not write to file "/opt/app/lib/tzdata-0.5.12/priv/tmp_downloads/335571_44358462/latest.tar.gz": no such file or directory
    (elixir) lib/file.ex:831: File.write!/3
    (tzdata) lib/tzdata/data_loader.ex:17: Tzdata.DataLoader.download_new/1
    (tzdata) lib/tzdata/data_builder.ex:9: Tzdata.DataBuilder.load_and_save_table/0
    (tzdata) lib/tzdata/release_updater.ex:41: Tzdata.ReleaseUpdater.poll_for_update/0
    (tzdata) lib/tzdata/release_updater.ex:17: Tzdata.ReleaseUpdater.handle_info/2
    (stdlib) gen_server.erl:616: :gen_server.try_dispatch/4
    (stdlib) gen_server.erl:686: :gen_server.handle_msg/6
    (stdlib) proc_lib.erl:247: :proc_lib.init_p_do_apply/3
Last message: :check_if_time_to_update

=CRASH REPORT==== 2-Nov-2017::22:23:52 ===
  crasher:
    initial call: Elixir.Tzdata.ReleaseUpdater:init/1
    pid: <0.2586.0>
    registered_name: tzdata_release_updater
    exception error: #{'__exception__' => true,
                       '__struct__' => 'Elixir.File.Error',
                       action => <<"write to file">>,
                       path =>
                           <<"/opt/app/lib/tzdata-0.5.12/priv/tmp_downloads/335571_44358462/latest.tar.gz">>,
                       reason => enoent}
      in function  'Elixir.File':'write!'/3 (lib/file.ex, line 831)
      in call from 'Elixir.Tzdata.DataLoader':download_new/1 (lib/tzdata/data_loader.ex, line 17)
      in call from 'Elixir.Tzdata.DataBuilder':load_and_save_table/0 (lib/tzdata/data_builder.ex, line 9)
      in call from 'Elixir.Tzdata.ReleaseUpdater':poll_for_update/0 (lib/tzdata/release_updater.ex, line 41)
      in call from 'Elixir.Tzdata.ReleaseUpdater':handle_info/2 (lib/tzdata/release_updater.ex, line 17)
      in call from gen_server:try_dispatch/4 (gen_server.erl, line 616)
      in call from gen_server:handle_msg/6 (gen_server.erl, line 686)
    ancestors: [<0.1411.0>,<0.1410.0>]
    message_queue_len: 0
    messages: []
    links: [<0.1411.0>]
    dictionary: [{random_seed,{27839,21123,25074}}]
    trap_exit: false
    status: running
    heap_size: 4185
    stack_size: 27
    reductions: 18757
  neighbours:

=SUPERVISOR REPORT==== 2-Nov-2017::22:23:52 ===
     Supervisor: {<0.1411.0>,'Elixir.Supervisor.Default'}
     Context:    child_terminated
     Reason:     {#{'__exception__' => true,
                    '__struct__' => 'Elixir.File.Error',
                    action => <<"write to file">>,
                    path =>
                        <<"/opt/app/lib/tzdata-0.5.12/priv/tmp_downloads/335571_44358462/latest.tar.gz">>,
                    reason => enoent},
                  [{'Elixir.File','write!',3,
                       [{file,"lib/file.ex"},{line,831}]},
                   {'Elixir.Tzdata.DataLoader',download_new,1,
                       [{file,"lib/tzdata/data_loader.ex"},{line,17}]},
                   {'Elixir.Tzdata.DataBuilder',load_and_save_table,0,
                       [{file,"lib/tzdata/data_builder.ex"},{line,9}]},
                   {'Elixir.Tzdata.ReleaseUpdater',poll_for_update,0,
                       [{file,"lib/tzdata/release_updater.ex"},{line,41}]},
                   {'Elixir.Tzdata.ReleaseUpdater',handle_info,2,
                       [{file,"lib/tzdata/release_updater.ex"},{line,17}]},
                   {gen_server,try_dispatch,4,
                       [{file,"gen_server.erl"},{line,616}]},
                   {gen_server,handle_msg,6,
                       [{file,"gen_server.erl"},{line,686}]},
                   {proc_lib,init_p_do_apply,3,
                       [{file,"proc_lib.erl"},{line,247}]}]}
     Offender:   [{pid,<0.2586.0>},
                  {id,'Elixir.Tzdata.ReleaseUpdater'},
                  {mfargs,{'Elixir.Tzdata.ReleaseUpdater',start_link,[]}},
                  {restart_type,permanent},
                  {shutdown,5000},
                  {child_type,worker}]

Dependencies

mix.exs

  defp deps do
    [
      {:phoenix, "~> 1.3.0"},
      {:phoenix_pubsub, "~> 1.0"},
      {:phoenix_ecto, "~> 3.2"},
      # {:mariaex, ">= 0.0.0"},
      {:phoenix_html, "~> 2.10"},
      {:gettext, "~> 0.11"},
      {:cowboy, "~> 1.0"},
      {:httpoison, "~> 0.13"},
      {:poison, "~> 3.1"},
      {:mix_docker, "~> 0.5.0"},

      # Dev or test deps
      {:phoenix_live_reload, "~> 1.0", only: :dev},
      {:hound, "~> 1.0", only: [:integration, :dev]},
      {:bypass, "~> 0.8", only: [:integration, :dev]},
      {:mox, "~> 0.2.0", only: [:test, :dev]},
    ]
  end

Crash on startup

15:57:28.719 [debug] Tzdata downloading new data from https://www.iana.org/time-zones/repository/tzdata-latest.tar.gz                                                                          
15:57:29.399 [debug] Tzdata data downloaded. Release version 2017c.                            
{:error,                                                                                       
 {:tzdata,                                                                                     
  {:bad_return,                                                                                
   {{Tzdata.App, :start, [:normal, []]},                                                       
    {:EXIT,                                                                                    
     {{:badmatch,                                                                              
       {:error,                                                                                
        {:shutdown,                                                                            
         {:failed_to_start_child, Tzdata.EtsHolder,                                            
          {:badarg,                                                                            
           [{:ets, :lookup, [:tzdata_current_release, :release_version], []},                  
            {Tzdata.ReleaseReader, :current_release_from_table, 0,                             
             [file: 'lib/tzdata/release_reader.ex', line: 47]},                                
            {Tzdata.ReleaseReader, :simple_lookup, 1,                                          
             [file: 'lib/tzdata/release_reader.ex', line: 14]},                                
            {Tzdata.ReleaseReader, :release_version, 0,                                        
             [file: 'lib/tzdata/release_reader.ex', line: 9]},                                 
            {Tzdata.DataBuilder, :load_and_save_table, 0,                                      
             [file: 'lib/tzdata/data_builder.ex', line: 11]},                                  
            {Tzdata.EtsHolder, :init, 1,                                                       
             [file: 'lib/tzdata/ets_holder.ex', line: 11]},                                    
            {:gen_server, :init_it, 2, [file: 'gen_server.erl', line: 365]},                   
            {:gen_server, :init_it, 6,                                                         
             [file: 'gen_server.erl', line: 333]}]}}}}},                                       
      [{Tzdata.App, :start, 2, [file: 'lib/tzdata/tzdata_app.ex', line: 15]},                  
       {:application_master, :start_it_old, 4,                                                 
        [file: 'application_master.erl', line: 273]}]}}}}}}                                    
iex(3)> 15:57:29.414 [info] Application tzdata exited: exited in: Tzdata.App.start(:normal, [])
    ** (EXIT) an exception was raised:                                                         
        ** (MatchError) no match of right hand side value: {:error, {:shutdown, {:failed_to_start_child, Tzdata.EtsHolder, {:badarg, [{:ets, :lookup, [:tzdata_current_release, :release_version], []}, {Tzdata.ReleaseReader, :current_release_from_table, 0, [file: 'lib/tzdata/release_reader.ex', line: 47]}, {Tzdata.ReleaseReader, :simple_lookup, 1, [file: 'lib/tzdata/release_reader.ex', line: 14]}, {Tzdata.ReleaseReader, :release_version, 0, [file: 'lib/tzdata/release_reader.ex', line: 9]}, {Tzdata.DataBuilder, :load_and_save_table, 0, [file: 'lib/tzdata/data_builder.ex', line: 11]}, {Tzdata.EtsHolder, :init, 1, [file: 'lib/tzdata/ets_holder.ex', line: 11]}, {:gen_server, :init_it, 2, [file: 'gen_server.erl', line: 365]}, {:gen_server, :init_it, 6, [file: 'gen_server.erl', line: 333]}]}}}}                                                              
            (tzdata) lib/tzdata/tzdata_app.ex:15: Tzdata.App.start/2                           
            (kernel) application_master.erl:273: :application_master.start_it_old/4     

Not sure what the issues is exactly. I confirmed that I'm using the latest 0.5.13 with latest Timex.

:tzdata_release_updater terminating

After updating to Elixir 1.2.1 I get the following error continously once i start my server

I use

{:tzdata, "~> 0.5.6"}
{:timex, "~> 0.19.2"},
[error] Task #PID<0.634.0> started from :tzdata_release_updater terminating
** (UndefinedFunctionError) undefined function Logger.log/3
    (logger) Logger.log(:debug, "Tzdata polling for update.", [module: Tzdata.ReleaseUpdater, function: "poll_for_update/0", line: 30])
    (tzdata) lib/tzdata/release_updater.ex:30: Tzdata.ReleaseUpdater.poll_for_update/0
    (tzdata) lib/tzdata/release_updater.ex:22: Tzdata.ReleaseUpdater.check_if_time_to_update/0
    (elixir) lib/task/supervised.ex:89: Task.Supervised.do_apply/2
    (elixir) lib/task/supervised.ex:40: Task.Supervised.reply/5
    (stdlib) proc_lib.erl:240: :proc_lib.init_p_do_apply/3
Function: #Function<0.63628506/0 in Tzdata.ReleaseUpdater.init/1>

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.