-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for returning metadata about time zones
If a system's time zone database has limited information, this makes it easier to debug.
- Loading branch information
Showing
4 changed files
with
94 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
defmodule Zoneinfo.Meta do | ||
alias Zoneinfo.TZif | ||
|
||
@moduledoc """ | ||
Metadata derived from TZif information | ||
The metadata here is mostly useful for checking the quality of the TZif files that | ||
were loaded. | ||
""" | ||
defstruct [:time_zone, :tz_string, :earliest_record_utc, :latest_record_utc, :record_count] | ||
|
||
@typedoc """ | ||
Zoneinfo.Meta contains information about one time zone | ||
* `:time_zone` - the name of the time zone | ||
* `:tz_string` - if a POSIX TZ string is available, this is it | ||
* `:earliest_record_utc` - the UTC time of the earliest time zone record | ||
* `:latest_record_utc` - the UTC time of the latest time zone record | ||
* `:record_count` -- the number of records | ||
""" | ||
@type t() :: %__MODULE__{ | ||
time_zone: String.t(), | ||
tz_string: String.t() | nil, | ||
earliest_record_utc: NaiveDateTime.t(), | ||
latest_record_utc: NaiveDateTime.t(), | ||
record_count: non_neg_integer() | ||
} | ||
|
||
@doc false | ||
@spec to_meta(String.t(), TZif.t()) :: t() | ||
def to_meta(time_zone, tzif) do | ||
%__MODULE__{ | ||
time_zone: time_zone, | ||
tz_string: tzif.tz_string, | ||
earliest_record_utc: ndt(Enum.at(tzif.periods, -2)), | ||
latest_record_utc: ndt(List.first(tzif.periods)), | ||
# The last record is the default for times before the first known one, so | ||
# it doesn't really count | ||
record_count: length(tzif.periods) | ||
} | ||
end | ||
|
||
defp ndt({gregorian_seconds, _utc_offset, _std_offset, _zone_abbr}) do | ||
Zoneinfo.Utils.gregorian_seconds_to_naive_datetime(gregorian_seconds) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
defmodule Zoneinfo.MetaTest do | ||
use ExUnit.Case | ||
|
||
alias Zoneinfo.Meta | ||
|
||
@fixture_path Path.join(__DIR__, "../fixture") | ||
|
||
defp parse_file(name) do | ||
Path.join(@fixture_path, name) | ||
|> File.read!() | ||
|> Zoneinfo.TZif.parse() | ||
end | ||
|
||
test "to_meta/2" do | ||
{:ok, tzif} = parse_file("Honolulu_v2") | ||
meta = Meta.to_meta("America/Honolulu", tzif) | ||
|
||
assert meta.time_zone == "America/Honolulu" | ||
assert meta.tz_string == "HST10" | ||
assert meta.earliest_record_utc == ~N[1896-01-13 22:31:26] | ||
# Yes, this looks strange. The file was shortened on purpose | ||
assert meta.latest_record_utc == ~N[1947-06-08 12:30:00] | ||
assert meta.record_count == 8 | ||
end | ||
end |