Why
W3Script has no date arithmetic. CTOD/DTOC only reformat, and YEAR/MONTH/DAY only decompose. There is no way to say "the day after this one", which demos/overtime.prg (#46) needs to derive TIMESHEET.WORKDATE from the week's Monday (WEEKDATE + (DOW-1) days).
Surfaced while designing #46: the demo should have nothing to work around.
Scope
DATEADD(date, n) → the ISO date n days later (n may be negative), as YYYY-MM-DD.
Follow the WEEK() precedent from #44 exactly:
- Computed in UTC (
Date.UTC + getUTC*) so a local timezone offset can never shift the day.
- Accepts ISO
YYYY-MM-DD or MM/DD/YY; composes with CTOD().
- ISO-shaped but impossible dates (
2024-02-30, 2023-02-29) return '' rather than silently rolling over, matching WEEK()'s round-trip rejection.
- Invalid input returns
''.
- Crosses month, year and leap-day boundaries correctly.
Must be registered in BUILTIN_FUNCTIONS in src/interpreter/Parser.ts. Implementing it in Builtins.ts alone leaves it unreachable (Unknown command: () — that's how the #4 built-ins shipped broken.
Tests
Per CLAUDE.md → Test discipline:
tests/Builtins.test.ts (direct) and tests/BuiltinsParse.test.ts (through the parser) — both are required.
- A Playwright case typing
? DATEADD(...) into the REPL and asserting the printed value.
- Cover: same month, month rollover, year rollover, leap day (
2024-02-28 → 2024-02-29), non-leap (2023-02-28 → 2023-03-01), negative n, n = 0, invalid input.
Docs
Built-ins tables in README.md and CLAUDE.md; CHANGELOG.md under v1.2.0.
Assistant parity
Not required — built-ins are expression-level functions used inside commands, not GUI-shaped actions, and none of them (ROUND, WEEK, YEAR, …) have sidebar entries. Note this in the PR.
Branch
feature/<name> off release/v1.2.0, PR targets release/v1.2.0. Blocks #46.
Why
W3Script has no date arithmetic.
CTOD/DTOConly reformat, andYEAR/MONTH/DAYonly decompose. There is no way to say "the day after this one", whichdemos/overtime.prg(#46) needs to deriveTIMESHEET.WORKDATEfrom the week's Monday (WEEKDATE + (DOW-1)days).Surfaced while designing #46: the demo should have nothing to work around.
Scope
DATEADD(date, n)→ the ISO datendays later (nmay be negative), asYYYY-MM-DD.Follow the
WEEK()precedent from #44 exactly:Date.UTC+getUTC*) so a local timezone offset can never shift the day.YYYY-MM-DDorMM/DD/YY; composes withCTOD().2024-02-30,2023-02-29) return''rather than silently rolling over, matchingWEEK()'s round-trip rejection.''.Must be registered in
BUILTIN_FUNCTIONSinsrc/interpreter/Parser.ts. Implementing it inBuiltins.tsalone leaves it unreachable (Unknown command: () — that's how the #4 built-ins shipped broken.Tests
Per
CLAUDE.md→ Test discipline:tests/Builtins.test.ts(direct) andtests/BuiltinsParse.test.ts(through the parser) — both are required.? DATEADD(...)into the REPL and asserting the printed value.2024-02-28→2024-02-29), non-leap (2023-02-28→2023-03-01), negativen,n = 0, invalid input.Docs
Built-ins tables in
README.mdandCLAUDE.md;CHANGELOG.mdunder v1.2.0.Assistant parity
Not required — built-ins are expression-level functions used inside commands, not GUI-shaped actions, and none of them (
ROUND,WEEK,YEAR, …) have sidebar entries. Note this in the PR.Branch
feature/<name>offrelease/v1.2.0, PR targetsrelease/v1.2.0. Blocks #46.