fix(timezone): display API datetimes in Europe/Paris (DST-safe)#141
Draft
dev-mansonthomas wants to merge 1 commit into
Draft
fix(timezone): display API datetimes in Europe/Paris (DST-safe)#141dev-mansonthomas wants to merge 1 commit into
dev-mansonthomas wants to merge 1 commit into
Conversation
Backend datetime fields were historically serialised as naive strings
(no TZ designator) and treated as local Paris time by the frontend,
which relied on a hardcoded -2h offset in my-slots.component.ts and on
Angular's default DatePipe (which uses the browser TZ). This was wrong
twice: it broke during DST transitions (CET vs CEST), and it produced a
2h offset for users outside Paris TZ.
The backend (rcq-functions-v2 #fix/timezone-utc-iso) now serialises
every datetime field as strict UTC ISO 8601 with a 'Z' suffix and
seconds precision: "YYYY-MM-DDTHH:MM:SSZ" (no fraction, no offset).
Frontend changes:
- New ParisDatePipe (src/app/pipes/paris-date.pipe.ts) using
Intl.DateTimeFormat with timeZone='Europe/Paris'. Handles:
* ISO strings with Z or explicit offset -> parsed as instant.
* Legacy naive strings (no Z, no offset) -> re-interpreted as UTC,
so the 5-minute Firestore cache window between backend deploy and
frontend deploy stays correct.
* Date objects and null/undefined -> identity / empty string.
Format presets: 'short' (dd/MM/yyyy HH:mm), 'medium', 'date',
'time'. Falls back to Angular DatePipe when an unknown preset is
passed, keeping behavioural compatibility.
- Templates migrated to | parisDate:
* tronc-history.component.html (depart_theorique, depart, retour)
* tronc-history-dialog.component.html (idem)
* register-tronc-state.component.html (depart_theorique)
- my-slots.component.ts: removed the -2h hack on tronc.depart /
tronc.retour. The component now sends new Date(...).toISOString(),
which produces strict "...Z" strings the backend accepts.
- cloud-function.service.ts: parseTroncDates now treats naive legacy
strings as UTC (parseAsUtcIfNaive helper) to keep parity with the
pipe during the cache window.
- shared.module.ts: declare + export ParisDatePipe so every feature
module that imports SharedModule can use | parisDate in templates.
Tests:
- src/app/pipes/paris-date.pipe.spec.ts covers summer (UTC+2),
winter (UTC+1), legacy naive, null/undefined, Date input, and
unknown preset fallback.
Coordination: paired with rcq-functions-v2 PR on the same branch name
(fix/timezone-utc-iso). Front-first deploy is safe because the pipe
accepts both legacy and ISO formats.
Smoke-test once backend is deployed on dev:
curl ... historique-tronc-queteur | jq '.[0].depart'
-> must end with "Z".
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Context
Backend datetime fields were historically serialised as naive strings (no TZ designator) and treated as local Paris time by the frontend, which relied on a hardcoded
-2hoffset inmy-slots.component.tsand on Angular's defaultDatePipe(which uses the browser TZ).This was wrong twice:
2hoffset for users outside Paris TZ.The backend (paired PR
rcq-functions-v2on the same branch namefix/timezone-utc-iso) now serialises every datetime field as strict UTC ISO 8601 with aZsuffix and seconds precision:YYYY-MM-DDTHH:MM:SSZ(no fraction, no offset).Frontend changes
New
ParisDatePipe(src/app/pipes/paris-date.pipe.ts)Uses
Intl.DateTimeFormatwithtimeZone='Europe/Paris'. Handles:Zor explicit offset → parsed as instant.Z, no offset) → re-interpreted as UTC, so the 5-minute Firestore cache window between backend deploy and frontend deploy stays correct.Dateobjects andnull/undefined→ identity / empty string.short(dd/MM/yyyy HH:mm),medium,date,time. Falls back to Angular'sDatePipefor unknown presets (behavioural compatibility).Templates migrated to
| parisDatetronc-history.component.html(depart_theorique,depart,retour)tronc-history-dialog.component.html(idem)register-tronc-state.component.html(depart_theorique)my-slots.component.tsRemoved the
-2hhack ontronc.depart/tronc.retour. The component now sendsnew Date(...).toISOString()which produces strict"...Z"strings the backend accepts.cloud-function.service.tsparseTroncDatesnow treats naive legacy strings as UTC (parseAsUtcIfNaivehelper) to keep parity with the pipe during the cache window.shared.module.tsDeclare + export
ParisDatePipeso every feature module that importsSharedModulecan use| parisDatein templates.Tests
src/app/pipes/paris-date.pipe.spec.tscovers:null/undefinedDateinputCoordination & deploy order
Paired with
rcq-functions-v2PR on the same branch namefix/timezone-utc-iso.Front-first deploy is safe because the pipe accepts both legacy and ISO formats — once this PR is merged and deployed on the 3 envs, the backend PR can be merged and deployed without any visible regression.
Smoke-test once backend is deployed on dev:
Out of scope
The
gcp-deploy.sh indexessubcommand (which unlocked the Mon historique page in the first place) is shipped separately in #140.Pull Request opened by Augment Code with guidance from the PR author