isnow(pattern) — a date/time language in a cell
isnow is tsvsheet's companion pattern language for repetition. One compact expression describes anything from a fixed instant to a complex recurrence and answers a single question: is it now? Inside a sheet, wrap isnow("…") in volatile() and it is a live boolean — the whole language, usable anywhere a formula is.
The pattern language
An isnow is a matcher, not a generator: it holds at an instant when every field constraint is satisfied. It is a strict superset of cron — sets, spans, exclusions, from-end counting, steps, since/until bounds — over one uniform per-field algebra. A field you leave out defaults to its zero, so M-F alone means weekdays at exactly midnight; add *:*:* to mean any instant on a weekday.
6 | every day at 06:00 |
|---|---|
M,W,F midnight | Mon/Wed/Fri at 00:00 |
11/ Th-[1] noon | last Thursday of November at noon |
M-F-[1] noon | the last business day of the month at noon |
+[90mn] | every 90 minutes — a true interval, crossing hours |
M-F +[30mn] >=9 <=17 | every 30 minutes, 9-to-5, on weekdays |
The language is specified grammar-first in tsvsheet/isnow (ANTLR4 grammar, 131-case conformance corpus); implementations exist in Go (library, CLI, HTTP server) and JS.
What it adds to a sheet
Every formula below was computed by the engine. wrapped in volatile(), isnow goes live: the playground, <tsv-sheet>, and any scheduled recompute re-evaluate it against the clock — so a sheet can carry its own schedule.
check⇥formula⇥reads workday?⇥=if(isnow("M-F *:*:*"), "workday", "weekend")⇥route alerts by weekday in-hours?⇥=isnow("M-F +[30mn] >=9 <=17")⇥gate a half-hourly window this-month?⇥=if(isnow("7/ *:*:*"), B5, C5)⇥pick July's rate over the default
- Schedules as data. An on-call rota, a rate table with seasonal windows, a maintenance calendar — the schedule itself lives in cells, diffable and reviewable, and the sheet evaluates it.
- Self-updating documents. A ```sheet fence or a served sheet whose cells read
isnowrenders differently at 09:00 than at midnight — with zero code, zero cron syntax errors, zero servers. - CI recomputation. A workflow that recomputes volatile sheets on a schedule turns a committed
.tsvtinto a living report — the roadmap's render-freshness gate is built for exactly this. - One language, everywhere. The same pattern text works in the
isnowCLI (isnow "M-F noon" && deploy), the HTTP server, JS, and your sheet — write the schedule once, evaluate it anywhere.
Try it
The isnow playground is the pattern instrument: type an isnow, watch a live verdict against your own clock, read the canonical form and the next five occurrences, or compose one field by field. Everything runs locally in your browser — the real grammar, no network.
In the sheet playground, put =isnow("*:*:*") | volatile() in a cell — TRUE, always. Then tighten it: =isnow("9:*:*") | volatile() holds only during the nine-o'clock hour; =isnow("M-F *:*:*") | volatile() only on weekdays. The volatile() refresh keeps them honest as the clock moves.
The standalone isnow CLI
Nothing extra is needed to use isnow() in a sheet — the function is built into every tsvsheet engine, everywhere it runs. Separately, the same language is available as a standalone isnow command for use outside spreadsheets: gate a shell pipeline (isnow "M-F noon" && deploy), derive the next occurrences, explain a pattern, wait until one holds, or serve it over HTTP.
$ brew install tsvsheet/tap/isnow # macOS & Linux > scoop install isnow # Windows (bucket: tsvsheet/scoop-bucket) $ go install github.com/tsvsheet/isnow.go/cmd/isnow@latest
.deb/.rpm packages and prebuilt binaries for every platform are on the releases page, built and attested exactly like the tsvsheet CLI — the install page's "verify what you run" applies to both.