Series: Time Processing Overview | Tutorial 1: Dates | Tutorial 2: Durations | Tutorial 3: Intervals | Tutorial 4
What you will learn
By the end of this tutorial you will be able to:
- Exploit the three modes of WOQL predicates: compute, validate, and classify
- Compose generators with filters to build business day calendars
- Use
andto chain temporal predicates into multi-step reasoning - Build fiscal calendar structures and verify them with Allen's algebra
- Detect gaps and overlaps between periods
- Coordinate deadlines across multiple entities with
range_min/range_max
Prerequisites
The Big Idea: Three Modes of Every Predicate
Most programming languages have functions that go one way: input → output. WOQL predicates are multi-directional. The same predicate can:
- Compute — give it inputs, get outputs
- Validate — give it all arguments, get yes/no
- Generate — give it partial information, get the missing piece, used to Classify here.
You have already seen this with date_duration (Tutorial 2) and interval_relation_typed (Tutorial 3). This tutorial shows you how to compose these modes to solve problems that would require complex procedural code in other systems.
Part 1: Business Day Calendars
Financial systems need to know which dates are business days. WOQL has no built-in "is_business_day" predicate — but you can build one by composing sequence (generator) with weekday (classifier) and less/lte (filter).
Step 1: Generate all dates in January, then filter to weekdays
Generate all dates in Jan, get each weekday number (Mon=1..Sun=7), keep only Mon-Fri.
What happened: sequence generated all 31 dates. weekday classified each one. lte(dow, 5) filtered out Saturday (6) and Sunday (7). The result is every business day in January 2025.
Step 2: Count business days in a month
How many business days in January 2025? Converts dates to strings before collecting, then counts.
Step 3: Find month-end dates that fall on weekdays
Month-end dates that are also business days. If a month ends on a weekend, it's excluded.
Part 2: Fiscal Calendar Construction
Build a complete fiscal calendar structure and verify it in a single query.
Step 4: Define and validate four quarters
Build Q1-Q4 as intervals, then verify each adjacent pair meets. One result = valid partition.
If you get one result, the quarters are correctly defined. Zero results means something is wrong — try changing a date to introduce a gap and see what happens.
Step 5: Quarter day-counts
How many days in each quarter? Note they're not all equal.
Part 3: Filing Deadlines and Coordination
Step 6: Compute a filing deadline
SEC 10-Q filings are due within 40 days after the fiscal quarter ends. The "as of" date (inclusive end of the period) is the starting point:
40 days after the as-of date (March 31) for a Q1 filing.
Step 7: Find earliest and latest deadlines
When multiple subsidiaries have different filing dates, find the reporting window:
Four subsidiaries, four deadlines. What's the consolidated window?
Step 8: Check which is the last business day before the deadline
Collect all business days into a list, then pick the maximum.
group_by collects business days into a list, range_max picks the latest. One row, one answer.
Part 4: Overlap and Gap Detection
Step 9: Detect overlapping periods
Does the audit period overlap with the reporting period? Check the relation.
Any result containing overlaps, overlapped_by, starts, started_by, during, contains, finishes, finished_by, or equals means the periods share at least some time.
Step 10: Validate no overlap between adjacent assignments
'meets' means zero gap AND zero overlap. The cleanest adjacency.
One result = clean handover. Zero results = something is wrong (gap or overlap).
Part 5: Rolling Windows and Sequence Composition
Step 11: Generate monthly reporting periods
For each month in H1, get both the first and last day.
What happened: sequence generated each gYearMonth. month_start_date and month_end_date converted each to concrete dates. You now have a complete monthly calendar.
Step 12: Monthly intervals for Allen's algebra
Construct an interval for each month in Q1 using start + P1M duration.
Part 6: Multi-Step Temporal Reasoning
This is where WOQL's composability truly shines. Chain multiple temporal predicates to answer complex questions.
Step 13: "What is the last business day of each month in H1 2025?"
This requires generating month-end dates, checking each for weekday, and if it's a weekend, stepping backward until you find a weekday. Here's a simplified version that shows the month-ends and their weekdays:
Which month-ends are weekdays (1-5) and which are weekends (6-7)?
Inspect the results: any dow of 6 (Saturday) or 7 (Sunday) means that month's last business day is actually the Friday before.
Step 14: Duration + interval + relation in one query
"Given a start date and a project duration, construct the project interval, then check if it overlaps with the Q2 reporting period."
Build a project interval from start+duration, classify its relation to Q2.
Design Patterns Summary
| Pattern | Predicates | Use case |
|---|---|---|
| Generate + Filter | sequence + weekday + lte | Business day calendars |
| Construct + Validate | interval + interval_relation_typed("meets") | Partition verification |
| Compute + Generate | date_duration + interval_relation_typed(v.rel) | Temporal reasoning |
| Generate + Transform | sequence(ym) + month_start_date | Monthly calendars |
| Aggregate + Compare | range_min / range_max | Deadline coordination |
| Chain + Compose | interval_start_duration + interval_relation_typed | Multi-step analysis |
Self-Check
- How would you find all Fridays in March 2025?
- What Allen relation would you check to verify two shifts have no gap?
- If
interval_relation_typed(v.rel, audit, reporting)returns"overlapped_by", what does that mean? - How would you find the next business day after a computed deadline?
- Why is WOQL better suited for temporal reasoning than a typical SQL query?
What You Learned
| Concept | Key Point |
|---|---|
| Three modes | Compute, validate, classify — same predicate, different binding patterns |
| Generate + Filter | sequence + weekday = business day calendar |
| Partition verification | Chain meets checks to prove no gaps or overlaps |
| Multi-step reasoning | and composes any predicates — duration, interval, relation |
| Deadline coordination | range_min / range_max across entity lists |
| Gap/overlap detection | Classify with interval_relation_typed — check the relation name |
Where to go next
- WOQL Time & Date Reference — exhaustive predicate-by-predicate documentation
- Allen's Interval Algebra Reference — all 13 relations with timeline diagrams
- EOM Preservation Rules — complete rule tables for month arithmetic
- Range Queries with triple_slice — O(log n) storage-level range queries