datetime
Absolute points in time: a date, a time of day and a time zone together, for deadlines that fall at a particular moment and for comparisons across time zones. Import it with IMPORT datetime; that also gives you daydate (for Date) and date-compat. Import time as well if you build TIME values with Time.
A DATETIME is stored as a moment in UTC together with its IANA time zone name. The functions that read it give local values in that time zone.
Example:
-- DateTime Example: Absolute points in time with timezones
IMPORT datetime
IMPORT timezone
IMPORT daydate
TIMEZONE IS SGT
-- DateTime construction from DATE + time components (uses document timezone SGT by default)
DECIDE `the deadline` IS Datetime (Date 31 12 2025) 17 0 0
#EVAL `the deadline` -- 2025-12-31T17:00:00+08:00
-- With explicit timezone override
DECIDE `london meeting` IS Datetime (DATE_FROM_DMY 1 6 2026) (TIME_FROM_HMS 9 0 0) "Europe/London"
#EVAL `london meeting` -- 2026-06-01T09:00:00+01:00
-- Date-only (midnight in document timezone)
DECIDE `start of year` IS Datetime (Date 1 1 2026)
#EVAL `start of year` -- 2026-01-01T00:00:00+08:00
-- DateTime construction from numbers (DMY order, like Date d m y)
DECIDE `full datetime` IS Datetime 31 12 2025 17 30 0
#EVAL `full datetime` -- 2025-12-31T17:30:00+08:00
DECIDE `date and hour` IS Datetime 15 6 2025 14
#EVAL `date and hour` -- 2025-06-15T14:00:00+08:00
DECIDE `date only` IS Datetime 25 12 2025
#EVAL `date only` -- 2025-12-25T00:00:00+08:00
DECIDE `month and year` IS Datetime 6 2025
#EVAL `month and year` -- 2025-06-01T00:00:00+08:00
DECIDE `year only` IS Datetime 2025
#EVAL `year only` -- 2025-01-01T00:00:00+08:00
-- Number constructors with explicit timezone
DECIDE `nyc new year` IS Datetime 1 1 2026 0 0 0 EST
#EVAL `nyc new year` -- 2026-01-01T00:00:00-05:00
-- DateTime from ISO-8601 string (JSON interop) - returns MAYBE DATETIME
DECIDE `from iso` IS Datetime "2025-06-15T10:30:00Z"
#EVAL `from iso` -- JUST OF (2025-06-15T18:30:00+0800)
-- ISO string with explicit display timezone - returns MAYBE DATETIME
DECIDE `from iso tz` IS Datetime "2025-06-15T10:30:00Z" SGT
#EVAL `from iso tz` -- JUST OF (2025-06-15T18:30:00+0800)
-- Extracting components (returns local values)
DECIDE `meeting` IS Datetime (Date 15 6 2025) (TIME_FROM_HMS 14 30 0)
#EVAL `Date of` `meeting` -- the date component
#EVAL `Time of` `meeting` -- the time component
#EVAL `Timezone of` `meeting` -- "Asia/Singapore"
#EVAL `the hour of` `meeting` -- 14
#EVAL `the day of` `meeting` -- 15
-- Predicates
DECIDE `afternoon check` IS `meeting` `is afternoon`
#EVAL `afternoon check` -- TRUE
-- Relative operations
#EVAL `at midnight` `meeting` -- same date at 00:00:00
#EVAL `at noon` `meeting` -- same date at 12:00:00
-- Cross-timezone comparison (compares UTC instants)
DECIDE `sg morning` IS Datetime (Date 1 6 2026) 8 0 0 SGT
DECIDE `london midnight` IS Datetime (Date 1 6 2026) 0 0 0 "Europe/London"
DECIDE `sg is later` IS `sg morning` GREATER THAN `london midnight`
#EVAL `sg is later` -- TRUE (SGT 08:00 = UTC 00:00, London 00:00 BST = UTC 23:00 prev day)
-- DateTime comparisons
DECIDE `before deadline` IS `meeting` LESS THAN `the deadline`
#EVAL `before deadline` -- TRUE
DECIDE `meeting is before deadline` IS `meeting` `is before` `the deadline`
DECIDE `deadline is after meeting` IS `the deadline` `is after` `meeting`
#EVAL `meeting is before deadline` -- TRUE
#EVAL `deadline is after meeting` -- TRUE
#EVAL `the earlier of` `meeting` `the deadline`
#EVAL `the later of` `meeting` `the deadline`
The document time zone
The forms of Datetime without a time zone use the document's time zone, so the file needs a TIMEZONE IS line. The timezone library has constants for common zones:
IMPORT datetime
IMPORT timezone
TIMEZONE IS SGT
Building a DATETIME
Every form below also takes a time zone as a last input, an IANA name such as "Europe/Paris", to use instead of the document's.
| Function | Gives | What it does |
|---|---|---|
Datetime date time |
DATETIME | A DATE and a TIME |
Datetime date h m s |
DATETIME | A DATE and the hour, minute and second |
Datetime date |
DATETIME | Midnight at the start of the date |
Datetime d m y h mn s |
DATETIME | Day, month, year, hour, minute and second |
Datetime d m y h mn |
DATETIME | Seconds are 0 |
Datetime d m y h |
DATETIME | Minutes and seconds are 0 |
Datetime d m y |
DATETIME | Midnight on that day |
Datetime m y |
DATETIME | Midnight on the 1st of the month |
Datetime y |
DATETIME | Midnight on 1 January |
Datetime text |
MAYBE DATETIME | Reads ISO 8601 text such as "2024-06-15T10:30:00Z" |
Datetime text tz |
MAYBE DATETIME | The same, shown in the time zone tz |
The number forms take the day before the month, as in Datetime 15 6 2024 10 30 0.
Reading a DATETIME
| Function | Gives | What it does |
|---|---|---|
Date of dt |
DATE | The local date |
Time of dt |
TIME | The local time of day |
Timezone of dt |
STRING | The IANA time zone name |
the hour of dt |
NUMBER | Local hour, 0 to 23 |
the minute of dt |
NUMBER | Local minute |
the second of dt |
NUMBER | Local second |
the day of dt |
NUMBER | Local day of the month |
the month of dt |
NUMBER | Local month |
the year of dt |
NUMBER | Local year |
dt `Datetime to serial` |
NUMBER | A serial number counted in UTC |
dt `is morning`, `is afternoon`, `is evening` |
BOOLEAN | Before 12:00; 12:00 to 17:59; 18:00 or later, in local time |
dt `is before noon`, `is after noon` |
BOOLEAN | Before 12:00; 12:00 or later |
Moving a DATETIME
| Function | Gives | What it does |
|---|---|---|
at midnight dt |
DATETIME | The same date at 00:00, in the same time zone |
at noon dt |
DATETIME | The same date at 12:00 |
dt `at` time |
DATETIME | The same date at another time of day |
Comparing DATETIME values
Comparisons use the moment in UTC, so 09:00 in Singapore is before 09:00 in London on the same day.
=,<,<=,>,>=and their word forms compare two DATETIME values.- dt1
`is before`dt2 and dt1`is after`dt2 read as sentences. `the earlier of`dt1 dt2 and`the later of`dt1 dt2 pick one of two values.