Skip to content

Add a timestamp formatter to std so date answers are computed, not guessed #73

Description

@sembrestels

Problem

@date is one-way: it parses a date string into a Unix timestamp (modules/std/src/helpers/date.ts). There is no helper going the other way, so a raw timestamp read from a contract can never be turned into something a human — or a model — can read.

This shows up most in the chat panel. Ask it "when does foo.eth expire" and it can fetch the expiry fine, but the answer comes back as a bare 1801234567, or as a calendar date the model computed in its head and got wrong. Same for vesting cliffs, GIVpower lock ends, stream end dates, governance deadlines — anything stored as a Unix timestamp.

3acf51c mitigated this by putting the current Unix timestamp in the chat system prompt, so the model can reason by subtraction instead of calendar arithmetic. That makes the arithmetic easier, but it is still the model doing it, and the result is not verifiable.

Proposal

Add a timestamp → string formatter to std, so the model (and users) can offload the conversion to the interpreter and read the answer out of a print, the same way balances already work:

load std
print @date:format(@date(now +30d))
# => "2026-08-30 14:02 UTC"

Two shapes worth weighing:

  • A separate helper, e.g. @date:format(timestamp format?). Keeps @date's return type (number) clean and its argument list untouched.
  • An option on @date, e.g. a --format flag. Fewer names to learn, but it makes the return type depend on an option, which the arg-def/codegen layer may not model well.

I lean towards the separate helper for the return-type reason.

Open questions:

  • Output format. A fixed ISO-ish UTC string is the safe default and keeps docs examples deterministic; a format argument (strftime-like, or a few named presets) is friendlier but adds surface.
  • Relative durations. @date:since / @date:until returning something like "about 7 months" would answer the "when does it expire" question directly, in one call. Could be a follow-up.
  • Timezone. Formatting in UTC only is the deterministic choice — local time would make test fixtures and doc examples machine-dependent.

Notes

  • Docs are generated from test docCases, so examples need to be self-contained and deterministic — feeding a fixed timestamp rather than @date(now).
  • Once this lands, the chat system prompt in apps/evmcrispr-terminal/src/ai/useChatAgent.ts should point at it, so the model calls the helper instead of doing the arithmetic itself.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions