Packages
tz_extra
0.8.0
0.45.0
0.44.0
0.43.0
0.42.0
0.41.0
0.40.0
0.39.0
0.38.0
0.37.0
0.36.0
0.35.0
0.34.0
0.33.0
0.32.0
0.31.0
0.30.0
0.29.0
0.28.0
0.27.0
0.26.0
0.25.0
0.24.0
0.23.0
0.22.1
0.22.0
0.21.1
0.21.0
0.20.1
0.20.0
0.17.0
0.16.7
0.16.6
0.16.5
0.16.3
0.16.2
0.16.1
0.16.0
0.15.1
0.15.0
0.8.0
0.7.0
0.6.0
0.5.0
0.4.0
0.3.0
0.2.0
0.1.0
Time zone-related utilities
Current section
Files
Jump to
Current section
Files
lib/compiler.ex
defmodule TzExtra.Compiler do
@moduledoc false
require TzExtra.IanaFileParser
import TzExtra.Helper
alias TzExtra.IanaFileParser
def compile() do
countries = IanaFileParser.countries()
time_zones =
IanaFileParser.time_zones_with_country(countries)
|> add_time_zone_links()
|> List.insert_at(0, %{coordinates: nil, country: nil, time_zone: "UTC", time_zone_links: []})
|> add_offset_data()
|> Enum.sort_by(&{&1.country && normalize_string(&1.country.name), &1.utc_offset, &1.time_zone})
contents = [
quote do
def version() do
unquote(Tz.version())
end
def countries_time_zones(with_utc: true) do
unquote(Macro.escape(time_zones))
end
def countries_time_zones() do
unquote(Macro.escape(Enum.filter(time_zones, & &1.time_zone != "UTC")))
end
def countries() do
unquote(Macro.escape(countries))
end
end
]
module = :"Elixir.TzExtra"
Module.create(module, contents, Macro.Env.location(__ENV__))
:code.purge(module)
end
defp add_offset_data(time_zones) do
Enum.map(time_zones, fn time_zone ->
{:ok, periods_by_year} = Tz.PeriodsProvider.periods_by_year(time_zone.time_zone)
latest_periods = Enum.filter(periods_by_year.minmax, & &1.to == :max)
utc_offset = hd(latest_periods).utc_offset
dst_offset = utc_offset + Enum.max_by(latest_periods, & &1.std_offset).std_offset
zone_abbr = Enum.min_by(latest_periods, & &1.std_offset).zone_abbr
dst_zone_abbr = Enum.max_by(latest_periods, & &1.std_offset).zone_abbr
time_zone
|> Map.put(:utc_offset, utc_offset)
|> Map.put(:dst_offset, dst_offset)
|> Map.put(:pretty_utc_offset, offset_to_string(utc_offset))
|> Map.put(:pretty_dst_offset, offset_to_string(dst_offset))
|> Map.put(:zone_abbr, zone_abbr)
|> Map.put(:dst_zone_abbr, dst_zone_abbr)
end)
end
defp add_time_zone_links(time_zones) do
link_time_zones = IanaFileParser.link_time_zones()
Enum.map(time_zones, fn time_zone ->
links =
link_time_zones
|> Enum.filter(
& &1.canonical_zone_name == time_zone.time_zone
&& !String.contains?(&1.link_zone_name, "GMT")
&& String.contains?(&1.link_zone_name, "/"))
|> Enum.map(& &1.link_zone_name)
Map.put(time_zone, :time_zone_links, links)
end)
end
end