Zoneless repeating event: occurrences are an hour off after DST, and a title-only --occurrence edit moves the day
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Aptitud para principiantes
- 50/100
Línea de trabajo
Start with internal/cmd/events_occurrence.go, tracing virtualOccurrence into occurrenceInstants and how the account zone is obtained; then read the zone handling in events.go and events_zone.go. Reproduce with a zoneless weekly event across the DST boundary and a title-only --occurrence edit. Done means the virtual and edited occurrence stay at 9:00 AM in the account zone; the issue also identifies the separate period API behavior as HEY-side work.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Summary
I was working on a project to sync Hey Calendar to a Google Calendar (https://github.com/edooley/hey-gcal) and stumbled across this: for a repeating event saved without a time zone (created in HEY's web app, so starts_at_time_zone is null), occurrences after a daylight saving change are an hour off in two ways:
- Read: the calendar period API behind
hey event week/hey event dayreports them at the series' original UTC time, while HEY's web calendar shows the correct local time. - Write (data change):
hey event edit <series> --occurrence <id> --apply-to currentwith only--titlesaves that UTC-based time, so the meeting moves an hour in HEY's web calendar.
Steps to reproduce
- Use a HEY account and machine in
America/Chicago. - In HEY's web app, create a weekly event "Test" on Wednesday 2026-10-21, 9:00–10:00 AM.
- Run
hey event week 2026-11-04 --json. DST ends on 2026-11-01. - Open HEY's web calendar on 2026-11-04.
- Edit only that day's title:
hey event edit <series> --occurrence <series>_2026-11-04 --apply-to current --title "Test (title-only edit)" - Run
hey event week 2026-11-04 --jsonagain, and check the web calendar.
Expected
- Steps 3–4: the API and the web calendar agree: 9:00 AM CST,
starts_at=2026-11-04T15:00:00Z. - Step 5: only the title changes. The day stays at 9:00 AM.
Actual
| Step | Source | 2026-11-04 |
|---|---|---|
| 3 | hey event week --json (virtual day) |
14:00:00Z = 8:00 AM CST ❌ |
| 4 | HEY web calendar | 9:00 AM ✅ |
| 5 | hey event edit … --title … response |
starts_at 14:00:00Z, new recording written out ❌ |
| 6 | hey event week --json (written-out day) |
14:00:00Z |
| 6 | HEY web calendar | 8:00 AM: the meeting moved ❌ |
- 2026-10-21, before the DST change, is correct everywhere (
14:00:00Z= 9:00 AM CDT). starts_at_time_zoneisnullon the series, itsparent, every occurrence, and the written-out day.- Zoned events (e.g. invites carrying
America/New_York) are not affected. - Passing the time explicitly (
--start-time 09:00 --end-time 10:00) writes15:00:00Zand fixes the day.
Where it comes from
- Read:
hey-sdk'sCalendarPeriods().Week/.Dayreturn HEY's JSON unchanged, andhey event weekdoesn't modifystarts_at. So the UTC-based time comes from HEY's period API, which disagrees with HEY's web calendar for the same day. - Write:
virtualOccurrence→occurrenceInstants(internal/cmd/events_occurrence.go) rebuilds a virtual day's start from the series. With noStartsAtTimeZoneit usestime.UTC, so the series' 14:00 UTC is kept on 2026-11-04 instead of its 9:00 local wall time. The comments inevents.go/events_zone.goalso describe HEY reading zoneless times as UTC, which matches the API but not the web app.
Suggested fix
- In
occurrenceInstants, expand a zoneless series in the HEY account's zone (accountZone), not UTC, so an edit keeps the day where the web app shows it. Consider refusing the edit when the account has no zone, aswriteZonedoes. - On HEY's side, the period API should expand zoneless series the way the web calendar does, so
starts_atis right for every API client.
Environment
- hey 1.9.0 (main at
02efc42), hey-sdk 0.32.1 - macOS,
America/Chicago - Related but separate: #585 / #563 (which local day an event lands on)
- Lenguaje dominante
- Go
- Estrellas
- 414
- Forks
- 53
- Merge medio
- 1 d 1 h
- PR fusionados (30 d)
- 75
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Sin plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de basecamp/hey-cli
-
TUI Calendar: Enter does nothing on a highlighted event (Day/Week), though the help bar shows "enter: open"Quizá libre de nuevo Un pull request para esta issue se cerró sin fusionarse. AbiertoCLI Only
Dificultad 2/5 1-3 horas Aptitud para principiantes 90/100
Los mantenedores suelen responder en 1 día
-
Dificultad 3/5 1-2 días Aptitud para principiantes 58/100
Los mantenedores suelen responder en 1 día
-
Bubble Up box is empty in the TUI and `hey box view`, but `hey bubble list` returns the emailsAbierto
Dificultad 3/5 1-2 días Aptitud para principiantes 65/100
Los mantenedores suelen responder en 1 día
-
Timed events show on their UTC day, not their local day, west of UTCPosiblemente ocupada @armada877 la tomó hace 11 días. Abierto
Dificultad 1/5 Menos de una hora Aptitud para principiantes 10/100
Los mantenedores suelen responder en 1 día
-
Dificultad 4/5 3-5 días Aptitud para principiantes 48/100
Los mantenedores suelen responder en 1 día
Todos los issues de basecamp/hey-cli
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
-
status:needs-review type:bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
Gentleman-Programming/engram#2079 ·
Los mantenedores suelen responder en 1 día
-
bug triage/pending
Dificultad 1/5 Menos de una hora Aptitud para principiantes 66/100
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 77/100
limitlessprojects/Go-Hybrid#1377 ·
Los mantenedores suelen responder en 1 día
-
bug report
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
Los mantenedores suelen responder en 3 días