Packages

A timezone data provider for Gleam!

Current section

Files

Jump to
gtz src gtz.erl
Raw

src/gtz.erl

-module(gtz).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/gtz.gleam").
-export([timezone/1, calculate_offset/2, local_name/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(" Functions to provide simple timezone support for other Gleam datetime libraries.\n").
-file("src/gtz.gleam", 25).
?DOC(
" Constructs a TimeZoneProvider type to be used with the Tempo package.\n"
" Returns an error if the timezone is not valid.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" import tempo/datetime\n"
"\n"
" let assert Ok(tz) = gtz.timezone(\"America/New_York\")\n"
"\n"
" datetime.literal(\"2024-06-21T06:30:02.334Z\")\n"
" |> datetime.to_timezone(tz)\n"
" |> datetime.to_string\n"
" // -> \"2024-01-03T02:30:02.334-04:00\"\n"
" ```\n"
).
-spec timezone(binary()) -> {ok, tempo:time_zone_provider()} | {error, nil}.
timezone(Name) ->
case 'Elixir.GTZ_FFI':is_valid_timezone(Name) of
true ->
{ok,
{time_zone_provider,
fun() -> Name end,
fun(Utc_naive_datetime) ->
{{Year, Month, Day}, {Hour, Minute, Second}} = tempo@naive_datetime:to_tuple(
Utc_naive_datetime
),
Offset@1 = case begin
_pipe = 'Elixir.GTZ_FFI':calculate_offset(
Year,
Month,
Day,
Hour,
Minute,
Second,
Name
),
_pipe@1 = gleam@time@duration:minutes(_pipe),
tempo@offset:from_duration(_pipe@1)
end of
{ok, Offset} -> Offset;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"gtz"/utf8>>,
function => <<"timezone"/utf8>>,
line => 35,
value => _assert_fail,
start => 1024,
'end' => 1200,
pattern_start => 1035,
pattern_end => 1045})
end,
Offset@1
end}};
false ->
{error, nil}
end.
-file("src/gtz.gleam", 73).
?DOC(
" Calculates the offset of a given timestamp in a specific time zone. Returns\n"
" an error if the time zone is invalid.\n"
"\n"
" This can be combined with the `gleam_time` package to convert timestamps to\n"
" calendar dates in a given time zone.\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" import gtz\n"
" import gleam/time/timestamp\n"
"\n"
" let my_ts =\n"
" 1_729_257_776\n"
" |> timestamp.from_unix_seconds\n"
"\n"
" let assert Ok(offset) =\n"
" gtz.calculate_offset(my_ts, in: \"America/New_York\")\n"
"\n"
" timestamp.to_calendar(my_ts, offset)\n"
" // -> #(\n"
" // calendar.Date(2024, calendar.October, 18),\n"
" // calendar.TimeOfDay(9, 22, 56, 0)\n"
" // )\n"
" ```\n"
).
-spec calculate_offset(gleam@time@timestamp:timestamp(), binary()) -> {ok,
gleam@time@duration:duration()} |
{error, nil}.
calculate_offset(Timestamp, Time_zone) ->
case 'Elixir.GTZ_FFI':is_valid_timezone(Time_zone) of
true ->
{{date, Year, Month, Day},
{time_of_day, Hours, Minutes, Seconds, _}} = gleam@time@timestamp:to_calendar(
Timestamp,
{duration, 0, 0}
),
_pipe@1 = 'Elixir.GTZ_FFI':calculate_offset(
Year,
begin
_pipe = Month,
gleam@time@calendar:month_to_int(_pipe)
end,
Day,
Hours,
Minutes,
Seconds,
Time_zone
),
_pipe@2 = gleam@time@duration:minutes(_pipe@1),
{ok, _pipe@2};
false ->
{error, nil}
end.
-file("src/gtz.gleam", 126).
?DOC(
" Returns the name of the host system's timezone.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" gtz.local_name()\n"
" // -> \"Europe/London\"\n"
" ```\n"
).
-spec local_name() -> binary().
local_name() ->
'Elixir.Timex.Timezone.Local':lookup().