| name | date-handling |
| description | Rules for writing correct date code in this project. The server stores all data in UTC — all date arithmetic, comparisons, and state must use UTC methods, never local time methods. |
Date Handling
Rule
The server stores all data in UTC. Always use UTC methods. Never use local date methods.
| Use | Avoid |
|---|
getUTCFullYear() | getFullYear() |
getUTCMonth() | getMonth() |
getUTCDate() | getDate() |
setUTCDate() | setDate() |
setUTCFullYear() | setFullYear() |
Date.UTC(y, m, d) | new Date(y, m, d) |
Converting a Date to an API string
toISOString().slice(0, 10) is correct only when d is already a UTC midnight date:
const toDateStr = (d: Date) => d.toISOString().slice(0, 10);
Constructing "today" as UTC midnight
const now = new Date();
When building a range that needs UTC midnight explicitly:
new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()))
Display (toLocaleDateString)
Always pass timeZone: "UTC" so the displayed date matches the stored UTC date:
d.toLocaleDateString("en-US", {
month: "short",
day: "numeric",
year: "numeric",
timeZone: "UTC",
});
Exception: Fluent UI Calendar widget
Calendar interprets its value prop as local time. This is the only place local date methods are allowed.
Reading from Calendar (onSelectDate) — normalize to UTC midnight immediately:
onSelectDate={(date) => {
setDate(
new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()))
);
}}
Writing to Calendar (value) — convert UTC midnight back to local midnight so the widget highlights the correct day:
value={
utcDate
? new Date(utcDate.getUTCFullYear(), utcDate.getUTCMonth(), utcDate.getUTCDate())
: undefined
}