DateTime Library
Absolute points in time combining date, time, and timezone for legal deadlines and cross-timezone comparisons. Stored internally as UTC; extractors return local values in the stored timezone.
Can be imported into L4 files with IMPORT datetime. Automatically imports daydate for date operations.
Location
jl4-core/libraries/datetime.l4
Prerequisites
Requires a TIMEZONE IS declaration in the document when using constructors without an explicit timezone parameter. Use with the timezone library for convenient timezone constants.
IMPORT datetime
IMPORT timezone
TIMEZONE IS SGT
Features
- DateTime construction with flexible overloads (date + time, numbers in DMY order, or ISO-8601 strings)
- Automatic use of document
TIMEZONE ISdeclaration - Explicit timezone override per value using IANA timezone strings
- Date, time, and timezone extraction from DateTime values
- Time-of-day predicates (morning, afternoon, evening)
- Cross-timezone comparison (UTC-based equality)
- Relative datetime operations (at midnight, at noon, at specific time)
- ISO-8601 string parsing for JSON interoperability
Key Functions
DateTime Construction (from DATE/TIME):
Datetime date time- Date + time in document timezoneDatetime date time tz- Date + time in explicit IANA timezoneDatetime date h m s- Date + hours/minutes/seconds in document timezoneDatetime date h m s tz- Date + hours/minutes/seconds in explicit timezoneDatetime date- Date at midnight in document timezoneDatetime date tz- Date at midnight in explicit timezone
DateTime Construction (from numbers, DMY order):
Datetime d m y h mn s- Day, month, year, hour, minute, second in document timezoneDatetime d m y h mn s tz- Same with explicit timezoneDatetime d m y h mn- Seconds default to 0Datetime d m y h- Minutes and seconds default to 0Datetime d m y- Midnight in document timezoneDatetime m y- 1st of month, midnightDatetime y- January 1st, midnight
All number-based constructors accept an optional trailing tz (STRING) for explicit timezone.
DateTime Construction (from strings, returns MAYBE DATETIME):
Datetime str- Parse ISO-8601 string (e.g."2024-06-15T10:30:00Z")Datetime str tz- Parse ISO-8601 string with explicit display timezone
DateTime Extractors:
Date ofdt - Get the date componentTime ofdt - Get the time component (local)Timezone ofdt - Get the IANA timezone namethe hour ofdt,the minute ofdt,the second ofdtthe day ofdt,the month ofdt,the year ofdt
DateTime Serial:
- dt
Datetime to serial- UTC-based serial number
Predicates:
is morning,is afternoon,is eveningis before noon,is after noon
Relative Operations:
at midnightdt - Same date, midnightat noondt - Same date, noon- dt
attime - Same date, different time
Comparators:
the earlier ofdt1 dt2the later ofdt1 dt2- dt1
is beforedt2, dt1is afterdt2 - Standard comparison operators: LESS THAN, GREATER THAN, AT MOST, AT LEAST
Example: DateTime Operations
-- 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`
See datetime.l4 source for all functions.