A user's time zone, for "their day" and "their evening": an IANA name
("Europe/Bucharest") kept in their private preferences
(Gamend.Accounts.Preferences), taken from the browser
(Intl.DateTimeFormat().resolvedOptions().timeZone, sent on connect) or
chosen in settings. A zone chosen by hand (choose/2) stays until the user
goes back to automatic: the browser no longer overwrites it
(manual?/1). Unknown or unset, everything falls back to UTC.
The tz database is passed to DateTime.shift_zone/3 explicitly, so a
host needs no global :time_zone_database config.
Summary
Functions
The user's own pick: name is kept and the browser stops replacing it;
nil goes back to automatic (the browser's zone, from the next visit).
The moment date begins for a user or a zone, as a UTC DateTime (UTC
midnight when the zone is unknown). Where midnight does not exist (a clock
change at 00:00), the first moment after it.
utc (default now) in a user's or a zone's local time; UTC when the zone
is unknown.
The user's local date (UTC's when their zone is unknown).
The hour (0-23) it is for the user now.
Whether the user picked their time zone by hand (choose/2).
Every time zone a person picks from, sorted: the IANA zones of
zone1970.tab (one per region, not every alias), plus UTC. Read once
from the tz package's own data and kept.
A user's time zone, or nil when unknown.
Save a user's time zone; an unknown name is refused, the same one is a no-op.
Whether name is a time zone the database knows.
Functions
@spec choose(Gamend.Accounts.User.t(), String.t() | nil) :: {:ok, Gamend.Accounts.User.t()} | {:error, term()}
The user's own pick: name is kept and the browser stops replacing it;
nil goes back to automatic (the browser's zone, from the next visit).
@spec day_start(Gamend.Accounts.User.t() | String.t() | nil, Date.t()) :: DateTime.t()
The moment date begins for a user or a zone, as a UTC DateTime (UTC
midnight when the zone is unknown). Where midnight does not exist (a clock
change at 00:00), the first moment after it.
@spec local(Gamend.Accounts.User.t() | String.t() | nil, DateTime.t()) :: DateTime.t()
utc (default now) in a user's or a zone's local time; UTC when the zone
is unknown.
@spec local_date(Gamend.Accounts.User.t() | String.t() | nil, DateTime.t()) :: Date.t()
The user's local date (UTC's when their zone is unknown).
@spec local_hour(Gamend.Accounts.User.t() | String.t() | nil, DateTime.t()) :: 0..23
The hour (0-23) it is for the user now.
@spec manual?(Gamend.Accounts.User.t() | nil) :: boolean()
Whether the user picked their time zone by hand (choose/2).
@spec names() :: [String.t()]
Every time zone a person picks from, sorted: the IANA zones of
zone1970.tab (one per region, not every alias), plus UTC. Read once
from the tz package's own data and kept.
@spec of(Gamend.Accounts.User.t() | nil) :: String.t() | nil
A user's time zone, or nil when unknown.
@spec put(Gamend.Accounts.User.t(), String.t()) :: {:ok, Gamend.Accounts.User.t()} | {:error, :invalid_time_zone | term()}
Save a user's time zone; an unknown name is refused, the same one is a no-op.
Whether name is a time zone the database knows.