agentfootprint
Version:
The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.
76 lines (75 loc) • 4.45 kB
TypeScript
/**
* time/instant — the ONE instant parser, with two named profiles.
*
* Pattern: one grammar, named profiles (never a second parser). Moved from
* `coverage/period.ts` (where it read a result's declared period)
* and `tools/declare.ts` (where a regex plus `Date.parse` checked
* an `iso-range` argument). Exact: no `Date.parse` guessing, no
* sub-millisecond loss.
* Role: L0 leaf (the time layer's one owner, `src/time/`). Imports
* nothing. Asked by `coverage/period.ts` (lenient) and, through
* `range.ts` · `splitRange`, by `tools/declare.ts` (strict).
* Emits: N/A.
*
* ## The two profiles
*
* | Profile | For | `t`/`z` lower case | second `60` | day past the month's end, hour 24 |
* |-----------|-----|--------------------|-------------|-----------------------------------|
* | `lenient` | a period a result DECLARES — RFC 3339 as a foreign minter may write it | accepted | accepted (compares as the next minute's `:00`) | refused |
* | `strict` | a value the library SENDS to a tool — the canonical spelling a backend such as Python's `datetime.fromisoformat` takes | refused | refused | refused |
*
* Both require a zone (`Z` or `±HH:MM`): an instant with no zone could be any
* of 24 hours, so it is refused rather than guessed.
*
* @example
* ```ts
* instantOf('2026-10-09T08:00:00-07:00', 'strict'); // { ms: 1791558000000, nanos: 0, offsetMinutes: -420, precision: 'second' }
* instantOf('2026-10-09t08:00z', 'strict'); // undefined — lower case is lenient-only
* instantOf('2026-02-30T08:00Z', 'lenient'); // undefined — 30 February does not exist
* toUtc('2026-10-09T08:00-07:00', 'strict'); // '2026-10-09T15:00:00Z'
* ```
*/
/** An ISO 8601 instant WITH an offset (`Z` or `±HH:MM`). */
export type InstantText = string;
/** Which spelling of an instant is accepted — see the module table. */
export type InstantProfile = 'lenient' | 'strict';
/**
* One instant, comparable exactly: whole milliseconds since the epoch, and the
* nanoseconds below that millisecond (0–999 999), so a 9-digit fraction is
* never rounded.
*/
export interface Instant {
readonly ms: number;
readonly nanos: number;
}
/** A parsed instant: the instant, the offset it was written in, and how finely it was written. */
export interface ParsedInstant extends Instant {
/** The written offset in minutes east of UTC (`Z` is 0). */
readonly offsetMinutes: number;
/** The finest part written: minutes only, seconds, or a fraction of a second. */
readonly precision: 'minute' | 'second' | 'fraction';
}
/** Days in `month` (1–12) of the proleptic Gregorian `year`. */
export declare const daysInMonth: (year: number, month: number) => number;
/** Milliseconds since the epoch of a UTC wall time. `setUTCFullYear`, never `Date.UTC`: the latter reads years 0–99 as 1900–1999. */
export declare function utcWallMs(year: number, month: number, day: number, hour: number, minute: number, second: number, millisecond?: number): number;
/**
* The instant a string names under `profile`, or `undefined` when it is not
* an ISO 8601 instant with a zone in that profile (a date alone, a time with
* no zone, a day that does not exist, hour 24, prose). The profile is always
* named by the caller: there is no default spelling of "an instant".
*/
export declare function instantOf(value: unknown, profile: InstantProfile): ParsedInstant | undefined;
/** -1 / 0 / 1 — `a` before, at, or after `b`. */
export declare function compareInstants(a: Instant, b: Instant): number;
/** `instant` moved by a whole number of milliseconds (negative moves it earlier). */
export declare function shiftInstant(instant: Instant, byMs: number): Instant;
/**
* The strict-profile spelling of `instant` in the offset `offsetMinutes`
* (`Z` when 0): seconds always written, a fraction only when it is not zero,
* with no trailing zeros. `undefined` when the offset is not a whole number of
* minutes within ±23:59, or the year in that offset falls outside 0000–9999.
*/
export declare function spellInstant(instant: Instant, offsetMinutes: number): InstantText | undefined;
/** The same instant spelled in UTC (`Z`), strict profile — or `undefined` when `value` is not an instant under `profile`. */
export declare function toUtc(value: unknown, profile: InstantProfile): InstantText | undefined;