mathieuprog / tz

Time zone support for Elixir
Apache License 2.0
147 stars 11 forks source link

`(CaseClauseError) no case clause matching: nil` for some lookups #8

Closed OldhamMade closed 3 years ago

OldhamMade commented 3 years ago
iex(1)> DateTime.now!("America/Argentina/Salta", Tz.TimeZoneDatabase)
** (CaseClauseError) no case clause matching: nil
    (tz 0.20.0) lib/time_zone_database.ex:43: Tz.TimeZoneDatabase.do_find_period_for_secs/3
    (tz 0.20.0) lib/time_zone_database.ex:33: Tz.TimeZoneDatabase.find_period_for_secs/3
    (elixir 1.12.0) lib/calendar/datetime.ex:623: DateTime.shift_zone_for_iso_days_utc/5
    (elixir 1.12.0) lib/calendar/datetime.ex:736: DateTime.now!/2

This is with Elixir 1.12.0 and Erlang 24.0 on macOS.

mathieuprog commented 3 years ago

Hi! Will look at it thank you!

OldhamMade commented 3 years ago

Hey there. Any updates on this? I've not had time myself to dig deeper, understandable if you haven't had time either.

mathieuprog commented 3 years ago

iex(1)> DateTime.now!("America/Argentina/Salta", Tz.TimeZoneDatabase)

DateTime<2021-09-21 09:45:52.535000-03:00 -03 America/Argentina/Salta>

elixir --version Erlang/OTP 22 [erts-10.7] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] Elixir 1.11.3 (compiled with Erlang/OTP 21)

Any thoughts? Can you run it now?

mathieuprog commented 3 years ago

Upgraded elixir/erlang, still working fine

Erlang/OTP 24 [erts-12.0] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] [jit] Elixir 1.12.3 (compiled with Erlang/OTP 22)

mathieuprog commented 3 years ago

The error is cause by the option :reject_time_zone_periods_before_year. Removing this option will prevent the error. That will be a quick solution before I fix it. Note that I don't even know if this option is worth it with the newer version of Tz because I think it might make no difference memory-wise. It needs to be measured (I just don't know how yet). Also this option was more intended for embedded devices that have a very limited amount of memory.

OldhamMade commented 3 years ago

Ah yes, apologies, I should have mentioned that I'm using that option.

It's the main reason I'm looking to switch to Tz: right now I'm using Tzdata but I'm running in a memory-restricted environment. I'm looking for something with a smaller memory footprint, and I only care about dates in the future, so Tz with the reject option looked perfect for my needs.

mathieuprog commented 3 years ago

Are you able to measure the memory footprint?

mathieuprog commented 3 years ago

Fixed in 0.20.1

mathieuprog commented 3 years ago

Still interested to know if you can measure memory footprint:)

OldhamMade commented 2 years ago

Confirmed: fixed for me. Thanks @mathieuprog.

FYI, here are some results from a naïve benchmark for my use-case on my local machine:

Operating System: macOS
CPU Information: Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz
Number of Available Cores: 16
Available memory: 64 GB
Elixir 1.12.0
Erlang 24.0.1

Benchmark suite executing with the following configuration:
warmup: 2 s
time: 30 s
memory time: 30 s
parallel: 4
inputs: none specified
Estimated total run time: 2.07 min

Benchmarking Tz...
Benchmarking Tzdata...

Name             ips        average  deviation         median         99th %
Tz            8.82 K      113.38 μs    ±52.02%       77.99 μs      324.99 μs
Tzdata        4.88 K      204.99 μs    ±17.63%      196.99 μs      352.99 μs

Comparison:
Tz            8.82 K
Tzdata        4.88 K - 1.81x slower +91.61 μs

Memory usage statistics:

Name           average  deviation         median         99th %
Tz            13.91 KB     ±0.09%       13.90 KB       13.95 KB
Tzdata        99.90 KB     ±0.09%       99.86 KB      100.09 KB

Comparison:
Tz            13.90 KB
Tzdata        99.90 KB - 7.18x memory usage +86.00 KB

My config is:

config :elixir, :time_zone_database, Tz.TimeZoneDatabase
config :tz, reject_time_zone_periods_before_year: 2019