Packages
timex
3.7.11
3.7.13
3.7.12
3.7.11
3.7.9
3.7.8
3.7.7
3.7.6
3.7.5
3.7.3
3.7.2
3.7.1
3.7.0
3.6.4
3.6.3
3.6.2
retired
3.6.1
3.6.0
3.5.0
3.4.2
3.4.1
3.3.0
3.2.2
3.2.1
3.2.0
3.1.25
retired
3.1.24
3.1.23
3.1.22
3.1.21
3.1.20
3.1.19
3.1.18
3.1.17
3.1.16
3.1.15
3.1.13
3.1.12
3.1.11
3.1.10
3.1.9
3.1.8
3.1.7
3.1.6
3.1.5
3.1.4
3.1.3
3.1.2
3.1.1
3.1.0
3.0.8
3.0.7
3.0.6
3.0.5
3.0.4
3.0.3
3.0.2
3.0.1
3.0.0
2.2.1
2.1.6
2.1.5
2.1.4
2.1.3
2.1.2
2.1.1
2.1.0
2.0.0
1.0.2
1.0.1
1.0.0
1.0.0-rc4
1.0.0-rc3
1.0.0-rc2
1.0.0-rc1
1.0.0-pre
0.19.5
0.19.4
0.19.3
0.19.2
0.19.1
0.19.0
0.18.2
0.18.1
0.18.0
0.17.0
0.16.2
0.16.1
0.16.0
0.15.0
0.14.3
0.14.2
0.14.1
0.14.0
0.13.5
0.13.4
0.13.3
0.13.2
0.13.1
0.13.0
0.12.9
0.12.8
0.12.7
0.12.6
0.12.5
0.12.4
0.12.3
0.12.2
0.12.1
0.12.0
0.11.0
0.10.2
0.10.1
0.10.0
0.9.0
0.8.0
0.7.1
0.6.0
0.5.0
0.4.8
0.4.7
0.4.6
Timex is a rich, comprehensive Date/Time library for Elixir projects, with full timezone support via the :tzdata package. If you need to manipulate dates, times, datetimes, timestamps, etc., then Timex is for you!
Current section
Files
Jump to
Current section
Files
lib/timezone/database.ex
defmodule Timex.Timezone.Database do
@behaviour Calendar.TimeZoneDatabase
alias Timex.Timezone
alias Timex.TimezoneInfo
@impl true
@doc false
def time_zone_period_from_utc_iso_days(iso_days, time_zone) do
db = Tzdata.TimeZoneDatabase
case db.time_zone_period_from_utc_iso_days(iso_days, time_zone) do
{:error, :time_zone_not_found} ->
# Get a NaiveDateTime for time_zone_periods_from_wall_datetime
{year, month, day, hour, minute, second, microsecond} =
Calendar.ISO.naive_datetime_from_iso_days(iso_days)
with {:ok, naive} <-
NaiveDateTime.new(year, month, day, hour, minute, second, microsecond) do
time_zone_periods_from_wall_datetime(naive, time_zone)
else
{:error, _} ->
{:error, :time_zone_not_found}
end
result ->
result
end
end
@impl true
@doc false
def time_zone_periods_from_wall_datetime(naive, time_zone) do
db = Tzdata.TimeZoneDatabase
if Tzdata.zone_exists?(time_zone) do
case db.time_zone_periods_from_wall_datetime(naive, time_zone) do
{:error, :time_zone_not_found} ->
time_zone_periods_from_wall_datetime_fallback(naive, time_zone)
result ->
result
end
else
time_zone_periods_from_wall_datetime_fallback(naive, time_zone)
end
end
# Fallback method which looks for a desired timezone in the process state
defp time_zone_periods_from_wall_datetime_fallback(naive, time_zone) do
# Try to pop the time zone from process state, validate the desired datetime falls
# within the bounds of the time zone, and return its period description if so
case Process.put(__MODULE__, nil) do
%TimezoneInfo{from: from, until: until} = tz ->
with {:ok, range_start} <- period_boundary_to_naive(from),
{:ok, range_end} <- period_boundary_to_naive(until) do
cond do
range_start == :min and range_end == :max ->
{:ok, TimezoneInfo.to_period(tz)}
range_start == :min and NaiveDateTime.compare(naive, range_end) in [:lt, :eq] ->
{:ok, TimezoneInfo.to_period(tz)}
range_end == :max and NaiveDateTime.compare(naive, range_start) in [:gt, :eq] ->
{:ok, TimezoneInfo.to_period(tz)}
range_start != :min and range_end != :max and
NaiveDateTime.compare(naive, range_start) in [:gt, :eq] and
NaiveDateTime.compare(naive, range_end) in [:lt, :eq] ->
{:ok, TimezoneInfo.to_period(tz)}
:else ->
{:error, :time_zone_not_found}
end
else
{:error, _} ->
{:error, :time_zone_not_found}
end
nil ->
time_zone_periods_from_wall_datetime_by_name(naive, time_zone)
end
end
# Fallback method which attempts to lookup the timezone by name
defp time_zone_periods_from_wall_datetime_by_name(naive, time_zone) do
with %TimezoneInfo{} = tz <- Timezone.get(time_zone, naive) do
{:ok, TimezoneInfo.to_period(tz)}
end
end
defp period_boundary_to_naive(:min), do: {:ok, :min}
defp period_boundary_to_naive(:max), do: {:ok, :max}
defp period_boundary_to_naive({_, {{y, m, d}, {hh, mm, ss}}}) do
NaiveDateTime.new(y, m, d, hh, mm, ss)
end
defp period_boundary_to_naive(_), do: {:error, :invalid_period}
end