You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We don't currently support timezones. Huddl times are stored as :utc_datetime, form inputs are interpreted as UTC, and every display
path (cards, hero, organize tables, calendar) formats the UTC value
directly via Calendar.strftime/2 with no shift. Users see times in
UTC, not in their local zone.
Current state
Huddlz.Communities.Huddl — starts_at and ends_at are :utc_datetime. Correct as canonical storage.
Huddlz.Communities.Huddl.Changes.CalculateDateTimeFromInputs builds
the datetime as DateTime.new(date, time, "Etc/UTC") and the source
comment explicitly flags this:
"Assuming the user's input is in their local timezone, we'll use UTC
for now. In a real app, you'd want to handle timezone conversion
properly."
LiveViews format UTC directly: lib/huddlz_web/live/huddl_live.ex
(huddl_month, huddl_day, format_meta_when), lib/huddlz_web/components/community_components.ex (format_datetime), lib/huddlz_web/live/organize_live.ex (multiple helpers), lib/huddlz_web/live/huddl_live/show.ex, etc.
The notification path is the one place that DOES localize: lib/huddlz/notifications/date_time_formatter.ex calls DateTime.shift_zone/2 against a time_zone from the payload. So
emails will format correctly if a TZ is supplied — but no caller
currently supplies one.
Tzdata is already a dependency (mix.exs) and configured
(config/config.exs sets :time_zone_database, Tzdata.TimeZoneDatabase).
No timezone field on User, Group, or Huddl.
Concrete bug
A huddl scheduled by a Phoenix-area organizer for "May 21 at 7:00 PM"
gets stored as 2026-05-22 02:00:00Z because the form input is
interpreted as UTC. On the discover card, huddl_month / huddl_day strftime that UTC datetime — so an Arizona viewer (UTC-7)
sees the date stamp MAY 22 and the meta line Wed · 2:00 AM, instead
of MAY 21 / Thu · 7:00 PM.
Proposed direction
Big enough to warrant a small design pass before code; rough shape:
Add time_zone to Huddl (string, IANA name e.g. America/Phoenix), defaulting from the group's TZ at create time.
Decide whether per-huddl override is allowed or whether it always
inherits from the group.
Add time_zone to Group so the organizer sets it once when
creating the group; defaults to the group's geocoded location's TZ
(we already geocode location to lat/lng — pair that with a TZ
lookup, or just ask the organizer).
Form input handling — interpret date + start_time as wall
time in the huddl's TZ, then convert to UTC for storage. Replace the DateTime.new(..., "Etc/UTC") call in CalculateDateTimeFromInputs with DateTime.new(date, time, time_zone).
Display — every formatter that takes a %DateTime{} shifts to
the huddl's TZ (or the viewer's TZ, if we add one) before strftime.
Probably worth extracting a Huddlz.DateTimeFormatter (or
generalizing Huddlz.Notifications.DateTimeFormatter) so there's
one place to enforce the rule.
Optional: user preference. Store time_zone on User and let
users opt to view all huddl times in their preferred TZ. Lower
priority than Component standardization (cards, buttons, forms) #1–4 — most users expect huddl times in the host's TZ
anyway.
Notifier wiring — supply the huddl's time_zone to the
notification payloads so the existing DateTimeFormatter actually
gets a non-default value.
Backfill — for existing huddlz, decide whether to assume a
default TZ (we can probably get away with a one-shot script that
sets every existing huddl's TZ to the group's TZ once Design system documentation #2 lands; the
stored UTC stays correct only if the original input was already in
UTC, which it isn't for any human-organized huddl. So: data fix
needed too. Small project, the practical move is probably "ask the
couple of test organizers to re-save").
Out of scope (file separately if pursued)
DST-boundary recurring huddlz — a weekly series spanning a DST switch
needs special handling (does the local wall time stay constant or
does the UTC offset stay constant?). The recurrence helper currently
just adds a fixed Duration in UTC.
Calendar export / iCal feeds — once we have TZ info, .ics outputs
should include TZID blocks.
Notes for whoever picks this up
Notifications already work — Huddlz.Notifications.DateTimeFormatter
is the template for what every other display path should look like.
Test fixtures (test/support/generator.ex) build datetimes with DateTime.add(DateTime.utc_now(), …) — those'll need a TZ-aware
variant once time_zone becomes part of the schema.
tzdata is already in deps; nothing new to add there.
Summary
We don't currently support timezones. Huddl times are stored as
:utc_datetime, form inputs are interpreted as UTC, and every displaypath (cards, hero, organize tables, calendar) formats the UTC value
directly via
Calendar.strftime/2with no shift. Users see times inUTC, not in their local zone.
Current state
Huddlz.Communities.Huddl—starts_atandends_atare:utc_datetime. Correct as canonical storage.Huddlz.Communities.Huddl.Changes.CalculateDateTimeFromInputsbuildsthe datetime as
DateTime.new(date, time, "Etc/UTC")and the sourcecomment explicitly flags this:
lib/huddlz_web/live/huddl_live.ex(
huddl_month,huddl_day,format_meta_when),lib/huddlz_web/components/community_components.ex(format_datetime),lib/huddlz_web/live/organize_live.ex(multiple helpers),lib/huddlz_web/live/huddl_live/show.ex, etc.lib/huddlz/notifications/date_time_formatter.excallsDateTime.shift_zone/2against atime_zonefrom the payload. Soemails will format correctly if a TZ is supplied — but no caller
currently supplies one.
Tzdatais already a dependency (mix.exs) and configured(
config/config.exssets:time_zone_database, Tzdata.TimeZoneDatabase).User,Group, orHuddl.Concrete bug
A huddl scheduled by a Phoenix-area organizer for "May 21 at 7:00 PM"
gets stored as
2026-05-22 02:00:00Zbecause the form input isinterpreted as UTC. On the discover card,
huddl_month/huddl_daystrftime that UTC datetime — so an Arizona viewer (UTC-7)sees the date stamp
MAY 22and the meta lineWed · 2:00 AM, insteadof
MAY 21/Thu · 7:00 PM.Proposed direction
Big enough to warrant a small design pass before code; rough shape:
time_zonetoHuddl(string, IANA name e.g.America/Phoenix), defaulting from the group's TZ at create time.Decide whether per-huddl override is allowed or whether it always
inherits from the group.
time_zonetoGroupso the organizer sets it once whencreating the group; defaults to the group's geocoded location's TZ
(we already geocode
locationto lat/lng — pair that with a TZlookup, or just ask the organizer).
date+start_timeas walltime in the huddl's TZ, then convert to UTC for storage. Replace the
DateTime.new(..., "Etc/UTC")call inCalculateDateTimeFromInputswithDateTime.new(date, time, time_zone).%DateTime{}shifts tothe huddl's TZ (or the viewer's TZ, if we add one) before strftime.
Probably worth extracting a
Huddlz.DateTimeFormatter(orgeneralizing
Huddlz.Notifications.DateTimeFormatter) so there'sone place to enforce the rule.
time_zoneonUserand letusers opt to view all huddl times in their preferred TZ. Lower
priority than Component standardization (cards, buttons, forms) #1–4 — most users expect huddl times in the host's TZ
anyway.
time_zoneto thenotification payloads so the existing
DateTimeFormatteractuallygets a non-default value.
default TZ (we can probably get away with a one-shot script that
sets every existing huddl's TZ to the group's TZ once Design system documentation #2 lands; the
stored UTC stays correct only if the original input was already in
UTC, which it isn't for any human-organized huddl. So: data fix
needed too. Small project, the practical move is probably "ask the
couple of test organizers to re-save").
Out of scope (file separately if pursued)
needs special handling (does the local wall time stay constant or
does the UTC offset stay constant?). The recurrence helper currently
just adds a fixed Duration in UTC.
.icsoutputsshould include
TZIDblocks.Notes for whoever picks this up
Huddlz.Notifications.DateTimeFormatteris the template for what every other display path should look like.
test/support/generator.ex) build datetimes withDateTime.add(DateTime.utc_now(), …)— those'll need a TZ-awarevariant once
time_zonebecomes part of the schema.tzdatais already in deps; nothing new to add there.