Skip to content

feat: DATEADD() date-arithmetic built-in (#52) - #53

Merged
DDecoene merged 1 commit into
release/v1.2.0from
feature/52-dateadd
Jul 9, 2026
Merged

feat: DATEADD() date-arithmetic built-in (#52)#53
DDecoene merged 1 commit into
release/v1.2.0from
feature/52-dateadd

Conversation

@DDecoene

@DDecoene DDecoene commented Jul 9, 2026

Copy link
Copy Markdown
Owner

Closes #52. Unblocks #46.

Why

W3Script has no date arithmetic. CTOD/DTOC only reformat, YEAR/MONTH/DAY only decompose — nothing can say "the day after this one". demos/overtime.prg needs it 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.

What

DATEADD(date, n) → the ISO date n days later (n may be negative), as YYYY-MM-DD.

  • Computed in UTC, so month/year/leap-day boundaries are exact and no local timezone offset can shift the day. (Day arithmetic in local time would also have to worry about DST.)
  • Impossible ISO dates (2023-02-29, 2024-13-01) return '' rather than silently rolling over, matching WEEK()'s round-trip rejection.
  • Accepts ISO YYYY-MM-DD or MM/DD/YY; composes with CTOD().
  • WEEK() already parsed dates in exactly this way, so that logic is extracted into a shared parseDateUTC() instead of duplicated. No behavior change to WEEK() (its tests are untouched and still pass).
  • Registered in BUILTIN_FUNCTIONS in Parser.ts — omitting that is how the More built-in functions: ROUND(), MOD(), MAX(), MIN(), TIME(), YEAR()/MONTH()/DAY() #4 built-ins shipped unreachable.

Assistant parity

Not surfaced, consistent with every other built-in (ROUND, WEEK, YEAR, …): built-ins are expression-level functions used inside commands, not GUI-shaped actions, and nothing in the sidebar or HELP enumerates them.

Test plan

Suites run serially (they share data/).

  • npx tsc --noEmit clean.
  • npm test369/369 vitest (was 358). New cases in tests/Builtins.test.ts (direct: same month, month/year rollover, leap day 2024-02-282024-02-29, non-leap 2023-02-282023-03-01, negative n, n = 0 normalising MM/DD/YY→ISO, Monday+4, invalid/impossible → '') and tests/BuiltinsParse.test.ts (through the parser, plus composing with CTOD).
  • npx playwright test84/84 (was 83). New parity-commands.spec.ts case types ? DATEADD(...) into the real REPL and asserts the printed value.

Docs

CHANGELOG.md, README.md and CLAUDE.md built-ins tables, test counts.

DATEADD(date, n) returns the ISO date n days later; n may be negative.
W3Script had no date arithmetic at all — CTOD/DTOC only reformat and
YEAR/MONTH/DAY only decompose — so there was no way to say "the day
after this one". demos/overtime.prg (#46) needs it to derive each
TIMESHEET.WORKDATE from the week's Monday.

Computed in UTC, so month, year and leap-day boundaries are exact and
no local timezone offset can shift the day. Impossible ISO dates return
'' rather than rolling over, matching WEEK().

WEEK() already parsed dates exactly this way, so that logic is
extracted into a shared parseDateUTC() rather than duplicated.

Registered in Parser's BUILTIN_FUNCTIONS, and covered directly, through
the parser, and end-to-end in the REPL — the three-way coverage the #4
built-ins lacked when they shipped broken.
@DDecoene
DDecoene merged commit e9d8ff5 into release/v1.2.0 Jul 9, 2026
2 checks passed
@DDecoene
DDecoene deleted the feature/52-dateadd branch July 9, 2026 18:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant