Zeitfolge

Zeitfolge — the language on one page. Every left-hand cell is real syntax.

Two kinds of time

timezone = Europe/Viennathe lens — civil literals below are read through it, answers shown through it. Never part of the data. Names are IANA Region/City (underscores for spaces) or UTCthe full list.
business = every weekday 09:00 .. 17:00 - holidaysthe working calendar — where the lens says where you are, this says when you work.
every zone this browser knows — the exact names timezone = accepts. Type to filter; click one to drop it into your program.
Some zones are listed under an older spelling (Asia/Calcutta for Asia/Kolkata, Europe/Kiev for Europe/Kyiv). The modern name works too — type it in full and it shows as accepted.

Declare

flight = 2026-07-13 10:40an instant. A bare date (2026-07-13) is a date, not a midnight.
trip = 2026-07-01 .. 2026-07-10an interval, half-open. A bare end date means through that day.
trips = a, bcollect — keeps each member's name
a | b   a & b   a - bmerge · intersect · subtract. Names travel through as labels.
hours = every weekday 09:00 .. 17:00a recurrence — unbounded. Bound it: hours & span, next 5 of hours, set - hours.
flight - 3 hours   flight + 2 dayshours/minutes are absolute; days/weeks are civil steps (DST-aware).
order + 3 business days   ticket + 8 business hoursthrough the working calendar: skip weekends and holidays; hours accumulate.
blocks = load "blocks"data from the host — a Lambda, a test, the Data panel.

See

now   ·   flight   ·   now in Asia/Tokyoa bare instant is a clock. in <zone> shows it in another zone.
now in Europe/Vienna, Asia/Tokyo, America/New_Yorka list of zones — one instant, one card, a row per lens: the world clock. Works on a meeting, and on show.
calendar   ·   calendar tripsthis month — or every month a stretch spans, its days shaded.
until flight   ·   since 2026-01-01countdown / count-up, live.
show trips in Europe/Londonthe stretches, big — one per option.
days of trips   ·   length of tripscivil days touched · absolute duration. They disagree across DST, on purpose.
partition a, bcut at every boundary — who covers each piece?
rolling days of trips in 180 days limit 90the windowed count — Schengen, tax residency, rate limits, quotas.
slots of free every 30 minutesthe booking page.
alone in x   ·   shared in xwhere exactly one member covers · where two or more overlap.
first 3 of x   ·   last 1 of x   ·   next 5 of ruleselectors. last 180 days (the window) is a different thing.

Plan & check

days of trips & last 180 days as of hamburgrun any line at a hypothetical present — time travel, free, because the program is a pure function of now.
assert days of trips & last 180 days <= 90a proposition. A failed assertion isn't an error — it's ok: false, so CI can gate on it.
assert rolling days of trips in 180 days limit 90the limit is never breached.
assert deploy not in freeze   ·   assert now in hoursis this moment inside that window? The window may be a recurrence.

A whole program

timezone = Europe/Vienna

trips = 2025-12-15 .. 2025-12-23,        # a line ending in an operator continues
        2026-03-27 .. 2026-05-11,
        2026-07-17 .. 2026-08-10

days of trips & last 180 days             # used as of today
rolling days of trips in 180 days limit 90
assert rolling days of trips in 180 days limit 90
calendar last 180 days                   # the whole window, one card

Comments start with #. Names must be bound before use. The full spec, with the reasoning: LANGUAGE.md — paste it to any LLM and it can write this language in one session.

SourceUTC underneath · the lens is presentation
Data (JSON)what a host passes to evaluate(src, {data}) — read with load "…"
ready
Answerslive — every strip is a stretch of the one timeline