ISO 8601 Time Processing in TerminusDB

Open inAnthropic

Time processing is one of the most error-prone areas in software engineering. A one-day boundary error in a financial reporting system can misclassify an entire quarter of transactions. A naive month-addition that ignores end-of-month rules can silently shift payment schedules. A missing timezone normalization can duplicate or skip hours around DST transitions.

TerminusDB provides a comprehensive set of WOQL predicates for working with ISO 8601 dates, times, durations, and intervals. More importantly, because WOQL is a logic language, its temporal predicates work bidirectionally — the same predicate that computes a date can also validate one, and the same predicate that generates a sequence can match against it. This dual nature is what makes WOQL uniquely powerful for temporal reasoning.

This section contains four progressive tutorials, a set of reference pages, and a collection of creative patterns for solving real business problems with temporal logic.


Getting Started

Every tutorial uses the WOQL Playground — an interactive editor embedded in each page that sends queries directly to your local TerminusDB instance. You can edit the code, run it, and see results immediately.

Setup

Option 1: Local TerminusDB (Recommended)

  1. Start TerminusDB using Docker:

    Example: Bash
    docker run --rm -p 6363:6363 terminusdb/terminusdb-server
  2. That's it! The playgrounds are pre-configured to use the _system database, which is always available. No database creation needed for time predicates.

  3. Optional: Click Settings on any playground to verify the connection:

    • Server URL: http://127.0.0.1:6363
    • Organization: admin
    • Database: _system
    • User: admin
    • Password: root

Option 2: DFRNT Cloud

  1. Get your API key from dfrnt.com after selecting your team

  2. Configure the playground: Click Settings and enter:

    • Server URL: https://dfrnt.com/api/hosted/YOUR_TEAM
    • Organization: Your team name
    • Database: _system (or any existing database)
    • User: Your email
    • Password: Your API key

Note: Time predicates are pure computations that work against the _system database. You only need to create a custom database when storing actual data (covered in tutorials that use triple or document operations).


Tutorials

Work through these in order. Each builds on concepts from the previous one.

Tutorial 1: Dates, Comparisons & Range Queries

You will learn: How TerminusDB represents dates and times, how to compare them, how to filter date ranges efficiently, and when to use triple_slice for O(log n) lookups vs computed range predicates.

Topics covered:

  • XSD date and time types (xsd:date, xsd:dateTime, xsd:dateTimeStamp, xsd:time)
  • Granular date types (xsd:gYear, xsd:gYearMonth, xsd:gMonth, xsd:gMonthDay, xsd:gDay)
  • Strict comparison: less, greater (and aliases lt, gt)
  • Non-strict comparison: lte, gte
  • Half-open range filtering: in_range
  • Storage-level range queries: triple_slice
  • "As of" date queries vs period queries
  • Timezone handling: when offsets matter and when they don't

Prerequisite: Basic WOQL familiarity (WOQL Getting Started)

Tutorial 2: Durations, Month Arithmetic & Sequences

You will learn: How durations work in ISO 8601, why month-based durations are different from day-based durations, how end-of-month preservation works, and how to generate date sequences for reporting calendars.

Topics covered:

  • Duration types: xsd:duration, xsd:dayTimeDuration, xsd:yearMonthDuration
  • Duration arithmetic: date_duration (tri-directional: start ↔ end ↔ duration)
  • Why P90D and P3M are fundamentally different
  • End-of-month (EOM) preservation rules
  • Non-reversibility of month arithmetic
  • Sequence generation: sequence for integers, decimals, dates, gYears, gYearMonths
  • Month boundary predicates: month_start_date, month_end_date, month_start_dates, month_end_dates
  • Date navigation: day_before, day_after
  • Calendar metadata: weekday, weekday_sunday_start, iso_week
  • Edge-of-range helpers: range_min, range_max

Prerequisite: Tutorial 1

Tutorial 3: Intervals & Allen's Temporal Algebra

You will learn: What temporal intervals are, why half-open intervals are essential for correct computation, how to construct and deconstruct xdd:dateTimeInterval values, and how Allen's 13 interval relations let you reason precisely about how periods relate to each other.

Topics covered:

  • The xdd:dateTimeInterval type and its four ISO 8601 forms
  • Inclusive vs half-open: the conversion problem
  • interval and interval_inclusive — construction and deconstruction
  • interval_start_duration and interval_duration_end
  • Typecasting between xdd:dateRange, xdd:dateTimeInterval, and xsd:duration
  • Allen's Interval Algebra: the 13 relations and why exactly one always holds
  • interval_relation — 5-argument form with explicit endpoints
  • interval_relation_typed — 3-argument form with interval values
  • Validation mode (ground relation) vs classification mode (unbound relation)
  • Partitioning verification: proving quarters tile a fiscal year

Prerequisite: Tutorial 2

Tutorial 4: Creative Temporal Patterns

You will learn: How to exploit WOQL's logic-programming nature — unification, backtracking, generators, and matchers — to solve temporal business problems that would require complex procedural code in other systems.

Topics covered:

  • The three modes of a WOQL predicate: compute, validate, classify
  • Generators: producing all dates, weeks, months in a range
  • Matchers: testing whether a value belongs to a generated set
  • Unification: extracting unknowns from partially-known temporal relationships
  • Composing generators with filters for complex calendar logic
  • Business day calendars using weekday + sequence
  • Rolling window analytics with interval_relation_typed
  • Fiscal calendar construction (quarters, tertials, custom periods)
  • Audit trail temporal integrity verification
  • Multi-subsidiary filing deadline coordination with range_min/range_max
  • Scheduling constraint satisfaction with Allen's relations
  • Period gap and overlap detection

Prerequisite: Tutorial 3


Reference Pages

These pages provide exhaustive predicate-by-predicate documentation. Use them alongside the tutorials.


Quick Reference: Which Predicate for Which Task

I want to...Use thisTutorial
Compare two datesless, greater, lte, gte1
Check if a date is in a rangein_range(value, start, end)1
Query stored dates by range (fast)triple_slice(doc, prop, val, lo, hi)1
Add days to a datedate_duration(start, result, "P30D")2
Add months with EOM rulesdate_duration(start, result, "P3M")2
Compute days between two datesdate_duration(start, end, duration)2
Generate every date in a rangesequence(date, start, end)2
Generate monthly datessequence(ym, "2025-01", "2026-01")2
Get month-end datesmonth_end_dates(date, start, end)2
Get day-of-weekweekday(date, dow)2
Find min/max in a listrange_min(list, min)2
Construct a half-open intervalinterval(start, end, iv)3
Construct from inclusive datesinterval_inclusive(start, end, iv)3
Check if intervals are adjacentinterval_relation_typed("meets", a, b)3
Classify the relation between periodsinterval_relation_typed(rel, a, b)3
Detect overlapping periodsinterval_relation_typed("overlaps", a, b)3
Generate all business days in Q1sequence + weekday + lte4
Verify quarters tile a fiscal yearinterval_relation_typed chain4
Find filing deadline from as-of datedate_duration(as_of, deadline, "P60D")4

Was this helpful?