diff options
| author | Claude Code <claude@terst.org> | 2026-08-15 17:59:12 +0000 |
|---|---|---|
| committer | Claude Code <claude@terst.org> | 2026-08-15 17:59:12 +0000 |
| commit | eb0932bddad0daa47c36cd20599944c3dc45482a (patch) | |
| tree | 4b0013e72af9a56ce496d8aeede7068d36fe4389 /reference_google_tasks_due_date_utc_quirk.md | |
Initial commit: tungsten's memory tree
Diffstat (limited to 'reference_google_tasks_due_date_utc_quirk.md')
| -rw-r--r-- | reference_google_tasks_due_date_utc_quirk.md | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/reference_google_tasks_due_date_utc_quirk.md b/reference_google_tasks_due_date_utc_quirk.md new file mode 100644 index 0000000..a0025dc --- /dev/null +++ b/reference_google_tasks_due_date_utc_quirk.md @@ -0,0 +1,16 @@ +--- +name: reference-google-tasks-due-date-utc-quirk +description: "Google Tasks API's due date field is date-only but always serialized as midnight UTC -- converting the instant into a display timezone (vs. re-anchoring the date) shifts dates in negative-offset zones" +metadata: + node_type: memory + type: reference + originSessionId: 647d8c60-e602-440e-b8b3-d8422fcbcb1d +--- + +The Google Tasks API's `due` field is conceptually date-only (no time-of-day is meaningful), but the API always serializes it as an RFC3339 timestamp fixed at midnight UTC, regardless of the user's actual timezone. E.g. a task due "July 29" comes back as `"2026-07-29T00:00:00.000Z"` even for a user in Honolulu. + +**The bug this causes:** if code does `dueDate.In(displayTZ)` on that parsed instant (converting the moment-in-time into the display timezone) instead of re-anchoring the same Y/M/D to local midnight, the date silently shifts backward for any timezone behind UTC. Midnight UTC becomes 2pm the *previous* day in UTC-10 (Pacific/Honolulu, doot's configured `config.GetDisplayTimezone()`) -- so every dated Google Task landed one calendar day earlier than Google actually reported. Symptom: "I have a scheduled task for tomorrow that's showing up today." + +**The fix** (`internal/api/google_tasks.go`, `getTasksFromList`): extract `y, m, d := dueDate.Date()` from the UTC-parsed timestamp (that Y/M/D *is* the intended calendar date) and rebuild `time.Date(y, m, d, 0, 0, 0, 0, displayTZ)` from those components -- never call `.In(displayTZ)` on a Google Tasks due-date instant directly. Fixed 2026-07-28, regression-tested in `google_tasks_test.go` (`TestGetTasksFromList_DueDateNotShiftedByNegativeOffsetTZ`) using the real Pacific/Honolulu location via a mocked HTTP tasks-list response. + +**How to apply:** if any *other* date-only field from an external API gets added to doot (a new integration, or a different Google Tasks/Calendar field), check whether that field has the same "date-only-but-serialized-as-UTC-midnight" convention before doing a naive `.In(displayTZ)` conversion on it. This is a genuinely common API convention (RFC3339 doesn't have a "date-only" type), not unique to Google Tasks. |
