tsvsheet logo tsvsheet

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.

patterns
6every day at 06:00
M,W,F midnightMon/Wed/Fri at 00:00
11/ Th-[1] noonlast Thursday of November at noon
M-F-[1] noonthe last business day of the month at noon
+[90mn]every 90 minutes — a true interval, crossing hours
M-F +[30mn] >=9 <=17every 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.

oncall.tsvt
checkformulareads
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 isnow renders 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 .tsvt into a living report — the roadmap's render-freshness gate is built for exactly this.
  • One language, everywhere. The same pattern text works in the isnow CLI (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.