All datetimes stored in UTC or with explicit timezone offset
Why it matters
Storing appointment datetimes without timezone information turns a scheduling platform into a time-bomb. A host in PST and a customer in EST reading the same DATETIME 14:00 literal interpret it as different wall-clock times. This violates CWE-686 (wrong type used for value) and ISO 25010 functional correctness. The failure mode is invisible until someone misses an appointment and support has to reconstruct what actually happened. Once daylight saving time transitions enter the picture, the mismatches compound: a DATETIME column that was correct in January silently drifts by an hour in March.
Severity rationale
Critical because timezone-naive storage causes silent appointment time mismatches that are invisible to both parties until a no-show occurs, with no automatic correction path.
Remediation
Use TIMESTAMP WITH TIME ZONE (timestamptz) in PostgreSQL for every appointment datetime column, and store a companion customer_timezone VARCHAR for display purposes. Convert incoming local times to UTC at the API boundary using an IANA library.
-- supabase/migrations/YYYYMMDDHHMMSS_appointments.sql
CREATE TABLE appointments (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
start_time TIMESTAMPTZ NOT NULL,
end_time TIMESTAMPTZ NOT NULL,
customer_timezone VARCHAR(50) NOT NULL
);
// src/lib/appointments.ts
import { fromZonedTime } from 'date-fns-tz'
export function toUtc(localIso: string, tz: string): Date {
return fromZonedTime(new Date(localIso), tz)
}
Call toUtc(body.startTime, body.timezone) before writing to the database in src/app/api/appointments/route.ts.
DetectionPro
The detection method for this pattern is part of AuditBuffet Pro.
The full method (what to look for, pass and fail conditions, and how results get reported) ships inside the Calendar & Availability Audit. The pattern definition, severity rationale, and remediation remain openly licensed under CC-BY-4.0.
External references
- cwe · CWE-686 — Function Call With Incorrect Argument Type — naive datetime storage without timezone context
- iso-25010:2011 · functional-correctness — Functional Correctness — appointment times must be unambiguous across timezones
Taxons
History
- 2026-04-18·v1.0.0·Initial import from booking-calendar-availability·automated