Timezone & DateTime
Time is a cross-domain concern (booking, schedules, roster, invoices, messaging). Timezone mistakes are among the most annoying and common bugs, so the system has explicit conventions.
Foundational principle
- Store absolute instants in UTC (for example
AutomationScheduler.ScheduledOnis UTC). - Display / local business logic uses the appropriate timezone (BU or user) — with
*LocalDate+TimeZoneIdwhen the "BU's local calendar" must be preserved. - APIs use one consistent UTC contract (timestamps are sent as UTC) so client/server do not interpret time differently.
Two service-area modes
| Mode | Meaning |
|---|---|
| Local | The whole enterprise has one timezone. |
| MultiZone | Multiple timezones; convert between source timezone (BU) and destination timezone (user). |
Mode is EnterpriseSetting.ServiceAreaId (NEW, INT NOT NULL DEFAULT 0) — authoritative at enterprise level. The old BU-level column (BusinessUnitSetting.ServiceAreaId) still exists but new code should ignore it (cleanup in a later phase).
Who owns what (timezone ownership)
| Concept | Owner | Field |
|---|---|---|
| Service-area mode | EnterpriseSetting | ServiceAreaId |
| User timezone | User | User.TimezoneIdentifier (Windows TZ ID, nullable) |
| BU timezone (source conversion in MultiZone) | BusinessUnitSetting | TimezoneIdentifier (required) |
| User date format | User | User.DateFormat (nullable) |
| User time format | User | User.TimeFormat (nullable) |
MultiZone conversion formula
text
dayjs.tz(rawValue, buIana).tz(userIana)Both IANA ids are resolved from Windows TZ ID via windowsToIana(). (The system stores Windows TZ IDs and converts to IANA for calculation.)
Some conventions/pitfalls
| Convention | Note |
|---|---|
| DateBased reminder | scheduledOn = local send time → UTC by BU timezone; DST is resolved by product rule. |
*Date vs *DateTime | *Date is date-only (no time → no timezone dependency); *DateTime includes time. |
*On vs *At | *On = audit/lifecycle; *At = event/integration timestamp. |
| Calendar/session local time | Display in local time; remove closure days before preview (see Subscription Step 1). |
| Booking cut-off | Stored as minutes (CutOffMinute), calculated by instant — be careful with timezone when comparing "is it past the deadline?". |
Related
- Database & storage —
*Date/*DateTime/*On/*Atconventions. - Communication → Automation — UTC
ScheduledOn+ local schedule.