DateTimeUTC is a FOAM3 property type that handles date-time values with consistent UTC timezone treatment. It ensures all datetime values are stored, parsed, and displayed in UTC, eliminating timezone ambiguity across users and servers.
Location: foam3/src/foam/lang/types.js
Extends: foam.lang.DateTime
Java Type: java.util.Date (inherited from the DateTimeJavaRefinement of foam.lang.DateTime in foam3/src/foam/java/refinements.js)
Related Utilities:
foam3/src/foam/util/DateUtil.js - Main utility class with parsing and formatting methodsfoam3/src/foam/parse/DateParser.js - Grammar-based parser supporting multiple date/datetime formatsDateTimeUTC provides three core guarantees:
DateUtil.parseDateTimeUTC()DateUtil.formatWithTimeControl(date, timeFirst, 'UTC')This eliminates timezone-related bugs where the same datetime appears differently to users in different timezones.
| Property Type | String Parsing | Time Component | Normalization | Use Case |
|---|---|---|---|---|
| Date | Local timezone | Ignored (sets to noon) | Noon UTC | Birth dates, deadlines |
| DateTime | DateParser, local timezone |
Preserved as-is | None (local) | User-local events |
| DateTimeUTC | Forced UTC | Preserved in UTC | All UTC | Logs, transactions, API timestamps |
What “sets to noon” means for a Date. The adapt rebuilds every value as noon UTC of the value’s local calendar day: new Date(Date.UTC(d.getFullYear(), d.getMonth(), d.getDate(), 12)) (src/foam/lang/types.js:242-250). Two values on the same local day become exactly equal, and consecutive days are exactly 24 hours apart, so plain equality is a same-day test. The time of day is discarded, and a test fixture built as a stored date + 24h - 1ms does not stay on the same day: it lands on the next day’s noon. Build same-day fixtures from the same timestamp and next-day fixtures with exactly + 24h. Use DateTime or DateTimeUTC when the instant matters.
DateTimeUTC uses foam.util.DateUtil.parseDateTimeUTC() which delegates to foam.parse.DateParser.parseDateTimeUTC():
1710511800000 → UTC timestamp maintainednew Date("2024-03-15T14:30:00Z") → Unchanged"2024-03-15 14:30:00" → 2024-03-15T14:30:00.000Z (UTC)2024-03-15T14:30:45.123, 2024-03-15T14:30:45, 2024-03-15T14:302024-03-15 14:30:45, 2024-03-15 14:302024/03/15T14:30:4503/15/2024 14:30:45, 03-15-2024 14:30, 01/15/2025 14:3020240315143045"2024-03-15" → 2024-03-15T00:00:00.000ZDate property which uses noon GMT)2024-03-15, 2024/03/15, 2024031503/15/2024, 03-15-2024, 0315202424-03-15, 24/03/15, 240315 (2-digit year with a fixed pivot: 00-49 → 2000-2049, 50-99 → 1950-1999)"2024-03-15T14:30:00+05:30" → 2024-03-15T09:00:00.000Z (UTC)2024-03-15T14:30:45Z (Zulu/UTC)2024-03-15T14:30:45+05:30, 2024-03-15T14:30:45-08:002024-03-15T14:30:45+0530, 2024-03-15T14:30:45-08002024-03-15T14:30:45+05, 2024-03-15T14:30:45-08DateTimeUTC always formats in UTC timezone via foam.util.DateUtil.formatWithTimeControl(date, timeFirst, 'UTC'). The property’s format(val, timeFirst = false) defaults timeFirst to false, so it includes the time unless null is passed. The examples below are the English form; in the browser the date and time follow the client locale:
"Mar 15, 2024" (when timeFirst is null)"Mar 15, 2024 14:30:00" (when timeFirst is false)"14:30:00 Mar 15, 2024" (when timeFirst is true)Format uses:
"2024-03-15" → 2024-03-15T00:00:00Z (midnight UTC)Date property behavior which sets to noon GMT"2024-03-15T14:30:00-05:00"2024-03-15T19:30:00Z ✅-05:00 is lost forever ❌"2024-03-15 14:30:00 EST" would not parse correctlyfoam3/src/foam/lang/types.jsfoam3/src/foam/util/DateUtil.jsfoam3/src/foam/parse/DateParser.jsfoam3/src/foam/util/test/DateUtilJSTest.js, foam3/src/foam/util/test/DateUtilTest.jsfoam3/src/foam/parse/test/DateParserTest.jsfoam3/doc/guides/StyleGuide.md