-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 => <>, 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().