Skip to content
docs
Arxo ↗

Time: effective, legal time, duration, editions

For LLMs7 sections

In one sentence: time answers the question “as of which date the case is computed”: effective switches rules on and off by legal time (legal_time), days_between measures duration in days, and an edition anchor (@source + in_force) dates a node by the act’s applicability. Take them when a norm holds “from … to …”, a period counts in days, or an article enters into force later than the case.

Legal time switches norms on and off, durations are measured in days, and edition anchors date nodes by the act’s applicability.

Instead ofSelection rule
Rule effective vs target window“Norm holds from 1 March” — effective [@2026-03-01, infinity); on the rule: outside the window there is no position at all. “Perform by 31 March” — target window: the position exists (PENDING/UNDETERMINED), the deadline has/has not passed. Different answers: “no norm yet” vs “period not started yet”
effective vs edition anchorThe rule’s own commencement date — effective. The act’s commencement date — edition lifecycle (in_force), to whose fragment @source leads: the node is dated by the anchor. A rule without effective but anchored to a future edition does not participate at an early date
days_between vs date additionDuration is only measured: days_between(due, paid) >= 30. due + 30 days — refusal LDC-E2108 (a date does not add a magnitude); days_between(due, paid) >= 30 days — the same refusal (Quantity vs Integer). A period is built by the period step (add_calendar_period)
Date vs InstantCivil date (@2026-03-01) — to a date; instant with offset (@2026-03-01T09:00:00+05:00) — to an instant. Mixing: statically LDC-E2108, in an execution term — TYPE_ERROR. Instants compare by moment, not by spelling
Fact-date comparison in the body vs governsRetroactivity in an act whose cases are written on the surface — by comparing the fact date in the body (so does the corpus). governs event_time … executes in the engine, but the surface does not record the axis onto a fact (assert … { valid …; } writes only valid_time), and a .lawtest case will never support such a rule

Grammar: time and dating (EBNF verbatim from the grammar)

Section titled “Grammar: time and dating (EBNF verbatim from the grammar)”
Show syntax reference

Time literals — dates, instants, their bodies, and the offset (where text and grammar differ, the grammar is canonical):

Grammar
temporal_literal = date_literal | time_literal | datetime_literal ;
date_literal = "@", digit, digit, digit, digit, "-", digit, digit, "-", digit, digit ;
time_literal = "@", digit, digit, ":", digit, digit, ":", digit, digit,
[ ".", digit, { digit } ] ;
datetime_literal = date_literal_body, "T", time_literal_body,
( "Z" | offset ) ;
date_literal_body = "@", digit, digit, digit, digit, "-", digit, digit, "-", digit, digit ;
time_literal_body = digit, digit, ":", digit, digit, ":", digit, digit,
[ ".", digit, { digit } ] ;
offset = ( "+" | "-" ), digit, digit, ":", digit, digit ;

Intervals — brackets and endpoints (infinity/-infinity are legal):

Grammar
interval_expression = expression ;
interval_literal = interval_left, interval_endpoint, ",",
interval_endpoint, interval_right ;
interval_left = "[" | "(" ;
interval_right = "]" | ")" ;
interval_endpoint = expression | "infinity" | "-infinity" ;

Applicability qualifiers — the rule validity window and the regulated-event window:

Grammar
effective_clause = "effective", interval_literal, ";" ;
governs_clause = "governs", identifier, interval_literal, ";" ;

Edition lifecycle events — dating nodes through the anchor:

Grammar
lifecycle_item = "adopted", temporal_literal, ";"
| "published", temporal_literal, ";"
| "in_force", interval_literal, ";"
| "suspended", interval_literal, ";"
| "restored", temporal_literal, ";"
| "repealed", temporal_literal, ";"
| "expired", temporal_literal, ";"
| "invalidated", temporal_literal, ";" ;

Package research.constructs.time_effective: a liability regime in force since 2026. Full code — the example package.

Arxo Law
rule PenaltyRegime2026 strict {
effective [@2026-01-01, infinity);
for p: Payer;
when registered_payer(p);
then penalty_regime_applies(p);
}

Case facts: registered_payer(alpha). Query: evaluate truth(penalty_regime_applies(alpha)).

Observed engine answer (installed law, semantics law.core/0.2):

Output
law test research.constructs.time_effective: мир research.constructs.time_effective
ok [research.constructs.time_effective#authored] tests/01-regime-active.lawtest / urn:query:research-time-01
ok [research.constructs.time_effective#authored] tests/02-regime-inapplicable.lawtest / urn:query:research-time-02
итого: 2 проверено, 2 прошли, 0 не прошли, 0 не исполнены; код 0

law engine check — check OK, no warnings. Sensitivity: changing legal_time from @2026-06-01 to @2025-06-01 with the same facts changes the answer from TRUE_ONLY to NEITHER — the rule does not participate (NOT_APPLICABLE), not “condition false”; removing the registered_payer fact at a date inside the window gives the same NEITHER by another route (body silence). The example is not vacuous.

Nearest wrong outcome: cutting the effective clause — the 2025 case answers TRUE_ONLY instead of NEITHER (counterfactual: the window decides).

  • Law: finite disability-benefit window (package kz.corpus.socialcode, Kazakhstan) — three rules with effective [@2023-07-01, @2027-01-01): a window with an end, not just a start (see corpus-forms.md).
  • Law: “no earlier than N days” as a guard (package tr.constitution, Türkiye) — days_between(submitted, year_start) >= 75 and the mirrored < 75: a pair of thresholds on one measure.
  • Standard/protocol: timely attestation (package us.code.apportionment, United States) — days_between(receipt, sent) <= 15: “within fifteen calendar days” as a measured-duration comparison.
  • Law: period by calendar step (package intl.vienna.succession_treaties, international) — during [appointed, add_calendar_period(appointed, 60 calendar_day)]: months and years are not measured but built by the period step.
  • Teaching case: research.constructs.time_overdue — the “thirty or more days” threshold (days_between(due, paid) >= 30): 41 days — TRUE_ONLY, 22 days — NEITHER (the rule stays silent, it does not refuse).
  • Law: detention over four days (package tr.constitution, Türkiye) — days_between(started, until) > 4 in a defeated rule with two unless provisos — delivery to a judge and extension under emergency/war: the same duration measure inside a more complex norm.

Table — observed runs of this directory’s examples (installed law, semantics law.core/0.2):

Legal timeFactsQuestionAnswerWhy
@2026-06-01registered_payerpenalty_regime_appliesTRUE_ONLYeffective window contains the legal time
@2025-06-01samesameNEITHEReffective starts @2026-01-01 — rule does not participate
@2026-03-01due 10.01, paid 20.02overdue_30TRUE_ONLYdays_between = 41 ≥ 30
@2026-03-01due 10.01, paid 01.02overdue_30NEITHER22 < 30 — silent, not refusing
  • Four context axes: legal_time (the law in force), decision_time (result moment), knowledge_time (data boundary), timezone. No axis is taken from the system clock.
  • A window without legal_time gives the rule NOT_APPLICABLE: answer NEITHER, why_not names the candidate with this status.
  • A node with anchors is excluded when ALL its dating editions are inapplicable at legal_time: the document carries issue EDITION_NOT_APPLICABLE (info), why_not — NOT_APPLICABLE. An edition with only adopted/published or timeless is outside dating: the node is excluded on no date.
  • Duration: days_between gives an Integer of calendar days, negative on reversed order; hours and minutes — hours_between, minutes_between over Instant.

Documented outcomes (earlier scenarios):

Law dateFactsQuestionAnswerWhy
@2025-06-01two memberships, one licencelicensed(acme, trade)FALSE_ONLYclosure in-window — explicit negative
@2026-03-01samesameNEITHERclosure window closed
@2026-03-01same, closure effective cut outsameFALSE_ONLYcounterfactual: the window decides
@2026-03-01debt_settledpenalty_waivedNEITHER + EDITION_NOT_APPLICABLEthe 2027 edition is not_yet
@2027-03-01samesameTRUE_ONLYedition in force
@2026-03-01same, @source anchor cut outsameTRUE_ONLYcounterfactual: the anchor dates the node
—days_between(@2026-02-20, @2026-01-10)DATA-41sign follows argument order
—days_between(@2026-01-10, @2026-02-20T00:00:00Z)DATATYPE_ERRORDate versus Instant
@2026-03-01filing 2025-12-31T23:30:00Zfiled_before_2026NEITHERby moment — 04:30 1 January Almaty
@2026-03-01filing 2025-12-31T18:00:00Zfiled_before_2026TRUE_ONLY23:00 31 December Almaty
  1. Rule silent on every date: check legal_time against effective and against the in_force of the edition @source leads to (pitfalls.md, item 1).
  2. Date vs Instant: check — LDC-E2108, execution — TYPE_ERROR (pitfalls.md, item 2).
  3. “30 days” as a magnitude: days_between(…) >= 30 days and due + 30 days — LDC-E2108 (pitfalls.md, item 3).
  4. Name in a window bound: effective [start, infinity) with an undeclared name — LDC-E1305; a bare name in a target window — LDC-E2115 (pitfalls.md, item 4).
  5. timeless together with lifecycle — LDC-E1305: two incompatible models of one edition (pitfalls.md, item 5).
  6. during/overlaps/before/after as predicates — LDC-E2102 (RESERVED); time conditions are written as date comparisons (pitfalls.md, item 6).
  7. Term window bound without a period policy — MISSING_POLICY (pitfalls.md, item 7).

Documentation for Arxo. Writings — blog.arxo.io.

Anonymous visit counts on stats.arxo.io, no cookies.