Packages
tz_extra
0.2.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/file_parser/zone_rule_parser.ex
defmodule TzExtra.FileParser.ZoneRuleParser do
@moduledoc false
def parse(file_path) do
File.stream!(file_path)
|> strip_comments()
|> strip_empty()
|> trim()
|> Enum.to_list()
|> parse_strings_into_maps()
end
defp strip_comments(stream) do
stream
|> Stream.filter(&(!Regex.match?(~r/^[\s]*#/, &1)))
|> Stream.map(&Regex.replace(~r/[\s]*#.+/, &1, ""))
end
defp strip_empty(stream) do
Stream.filter(stream, &(!Regex.match?(~r/^[\s]*\n$/, &1)))
end
defp trim(stream) do
Stream.map(stream, &String.trim(&1))
end
defp parse_strings_into_maps([]), do: []
defp parse_strings_into_maps([string | tail]) do
map =
cond do
String.starts_with?(string, "Link") ->
parse_link_string_into_map(string)
String.starts_with?(string, "Zone") ->
parse_zone_string_into_map(string)
true ->
nil
end
if(map == nil, do: [], else: [map]) ++ parse_strings_into_maps(tail)
end
defp parse_link_string_into_map(link_string) do
Enum.zip([
[:canonical_zone_name, :link_zone_name],
tl(String.split(link_string, ~r{\s}, trim: true, parts: 3))
|> Enum.map(& String.trim(&1))
])
|> Enum.into(%{})
|> Map.put(:record_type, :link)
end
defp parse_zone_string_into_map(zone_string) do
Enum.zip([
[:name, :std_offset_from_utc_time, :rules, :format_time_zone_abbr, :to],
tl(String.split(zone_string, ~r{\s}, trim: true, parts: 6))
|> Enum.map(& String.trim(&1))
])
|> Enum.into(%{})
|> Map.take([:name])
|> Map.put(:record_type, :zone)
end
end