Name
go-isnow — go-isnow — the isnow date/time pattern language as an importable Go library.
The isnow date/time pattern language as an importable Go library. An isnow is one compact expression describing anything from a fixed instant to a complex recurrence, answering a single question: is it now? go-isnow parses a pattern into an immutable Pattern, tests membership at any instant, and derives past and future occurrences — with no filesystem, network, or clock access of its own.
The library is the one engine behind the isnow CLI and the ISNOW(...) spreadsheet function in go-tsvsheet. Import it to evaluate isnow patterns from your own Go programs, services, or schedulers.
Install
go get github.com/tsvsheet/go-isnowAPI reference: pkg.go.dev/github.com/tsvsheet/go-isnow.
Quickstart
package main
import (
"fmt"
"time"
isnow "github.com/tsvsheet/go-isnow"
)
func main() {
p, err := isnow.Parse("M,W,F noon")
if err != nil {
panic(err) // one of the four sentinels, matchable with errors.Is
}
at := time.Date(2026, 7, 13, 12, 0, 0, 0, time.UTC) // a Monday
fmt.Println(p.Holds(at)) // true
fmt.Println(p.Canonical()) // */*/* Monday,Wednesday,Friday 12:00:00
next, ok := p.Next(at)
fmt.Println(ok, next) // true 2026-07-15 12:00:00 +0000 UTC (Wednesday)
}Parse recognizes the pattern, resolves symbols (M, noon, mwf) and the shorthand ladder, validates every field domain, and returns an immutable Pattern. Holds is the defining operation — membership of an instant — and Next/Prev derive occurrences from it.
The language
One expression constrains up to seven fields — year, month, day, weekday, hour, minute, second — with a shorthand ladder that infers which fields you meant: 6 is 6 AM daily, M noon is Mondays at noon, 12/25 mn is every Christmas at midnight. Fields take lists (M,W,F), spans (9-17, M-F), steps (+[15], Th+[2] for the 2nd Thursday), from-end selection (-1w), periodic intervals (+[90mn]), bounds (>=2026, <=17:30), and exclusions (! 12/25). The language itself — grammar, semantics, and the cross-implementation conformance corpus — is specified in the isnow repo (SPECIFICATION.md).
Core API
Parse(src PatternText) (Pattern, error)— compile pattern source into an immutablePattern.PatternTextis the exported source-text type, so callers convert their string input at the call site.Pattern.Holds(at time.Time) bool— the membership test: does the isnow hold at the instant? Evaluated in the instant’s own location, truncated to whole seconds.Pattern.Next(from) / Prev(from) (time.Time, bool)— the earliest occurrence strictly after (or latest strictly before) an instant, or false when none exists within the pattern’s window or the 100-year search horizon.Pattern.NextContext(ctx, from) / PrevContext(ctx, from)— the same derivations with cancellation, for pathological patterns whose scan would otherwise pin a CPU.Pattern.Canonical() string— the fully-qualified seven-field form (alsoString()); parsing a canonical form is a fixed point.Pattern.Explain() string— a deterministic English description of the pattern.Is(src PatternText, at time.Time) (bool, error)— the one-shot form: Parse then Holds.Code(err error) string— the stable cross-implementation code (syntax,symbol,range,context) of a library error.
Pattern is immutable and every method is a value receiver: patterns are safe to copy, alias, and share across goroutines.
Errors
Parse rejects a bad pattern with one of four errs.Const sentinels shared by every isnow implementation, matchable with errors.Is:
ErrSyntax— a malformed pattern the grammar rejects.ErrSymbol— an unknown or ambiguous weekday/time/unit name (xyzzy, an ambiguous prefix likeT).ErrRange— a value outside its field’s domain (25:00).ErrContext— a grammatical but semantically invalid construct (///, a weekday bound).
Design
The public surface is one package — github.com/tsvsheet/go-isnow — a thin, documented facade. The recognizer (the grammar repo’s ANTLR-generated parser), the ladder, the field compiler, and the derivation engine are all internal; no parser or grammar type escapes into the public API. The library is clock-free by construction — every query takes the instant to evaluate against — so callers inject their own time source and results are deterministic and testable. Behavior is pinned by the cross-implementation conformance corpus in the grammar repo.
Related
- isnow — the language: grammar, specification, and conformance corpus.
- isnow.go — the CLI built on this library.
- isnow.js — the JavaScript implementation.
- go-tsvsheet — the tsvsheet spreadsheet engine, whose
ISNOW(...)function this library powers.