Durations past 24 hours and the basic date/time functions

- New cell format "Dauer" ([h]:mm): hours keep counting past 24 (37:30).
  A formula left on "Automatisch" whose numeric inputs are all times or
  durations (=SUM over working times, =end-start) displays as a duration.
  Typing 24 or more hours (37:30) enters a duration.
- "Datum + Zeit" shows a bare time of day (< 1 day) without the epoch
  date 30.12.1899.
- New functions: YEAR, MONTH, DAY, HOUR, MINUTE, SECOND, WEEKDAY,
  ISOWEEKNUM, WEEKNUM, EDATE, EOMONTH, DAYS, DATEDIF, NETWORKDAYS,
  WORKDAY, DATEVALUE, TIMEVALUE. Where Excel defaults to US conventions,
  ISO 8601 is the default: weeks start Monday (WEEKDAY -> Monday = 1),
  WEEKNUM is the ISO week. Excel's other types stay available.
- Command reference and README document all of it; the README test
  count is updated to 553.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
wkh
2026-09-28 02:21:48 +02:00
co-authored by Claude Opus 5.5
parent 604794118b
commit c4d2712903
11 changed files with 620 additions and 21 deletions
+40 -7
View File
@@ -12,7 +12,7 @@ Eine browserbasierte Tabellenkalkulation nach dem Vorbild von **Apple Numbers**.
```bash
npm install
npm run dev # Vite-Devserver
npm run test # Vitest-Suite (Engine + Store + IO), 528 Tests
npm run test # Vitest-Suite (Engine + Store + IO), 553 Tests
npm run build # Typecheck + Produktionsbuild
npm run lint # ESLint (flat config)
```
@@ -878,7 +878,10 @@ das Dropdown, ohne die Bearbeitung selbst abzubrechen.
`MIN`, `MAX`, `COUNT`, `CONCAT` (Alias `CONCATENATE`), `IF(Bedingung; Dann;
Sonst?)`, `AND(Bedingung1; Bedingung2; …)`, `OR(Bedingung1; Bedingung2; …)`,
`NOT(Bedingung)`, `DATE(Jahr; Monat; Tag)`, `TIME(Std; Min; Sek)`, `TODAY()`,
`NOW()`, `XLOOKUP(Suchwert; Suchbereich; Rückgabebereich; [WennNichtGefunden];
`NOW()`, die Datums-/Zeitfunktionen `YEAR`, `MONTH`, `DAY`, `HOUR`,
`MINUTE`, `SECOND`, `WEEKDAY`, `ISOWEEKNUM`, `WEEKNUM`, `EDATE`, `EOMONTH`,
`DAYS`, `DATEDIF`, `NETWORKDAYS`, `WORKDAY`, `DATEVALUE`, `TIMEVALUE` (s. „Datum
& Zeit" unten), `XLOOKUP(Suchwert; Suchbereich; Rückgabebereich; [WennNichtGefunden];
[Vergleichsmodus]; [Suchmodus])` — plus alle über den **„fx"-Button** angelegten
benutzerdefinierten Funktionen (siehe „Benutzerdefinierte Funktionen" oben),
die sich für den Aufrufer identisch verhalten. Argumente gemischt:
@@ -922,7 +925,8 @@ ohne Zusatzaufwand: `=fällig - rechnungsdatum` zählt Tage, `=rechnungsdatum
und sofort mit dem passenden Format angezeigt — genau wie in Excel/Numbers.
Erkannt werden ISO (`2026-09-02`, auch mit `14:30`/`14:30:15` angehängt)
und Punkt-Daten (`02.09.2026`, `02.09.26`, ebenfalls mit Uhrzeit), sowie
reine Uhrzeiten (`14:30`). **Absichtlich nicht** erkannt: Schrägstrich-Daten
reine Uhrzeiten (`14:30`); ab 24 Stunden (`37:30`) wird daraus eine
**Dauer**. **Absichtlich nicht** erkannt: Schrägstrich-Daten
(`02/09/2026`) — Tag-zuerst vs. Monat-zuerst ist über die unterstützten
Locales (en-US ist monatzuerst, alle anderen tagzuerst) nicht eindeutig
auflösbar; falsches Raten würde das Datum lautlos verfälschen, deshalb
@@ -932,13 +936,39 @@ ohne Zusatzaufwand: `=fällig - rechnungsdatum` zählt Tage, `=rechnungsdatum
Datums-/Zeitwert (Überlauf wie in Excel erlaubt: `DATE(2026;13;1)` =
01.01.2027, `TIME(25;0;0)` = 01:00 des Folgetags-Anteils); `TODAY()` /
`NOW()` liefern das aktuelle Datum bzw. Datum+Uhrzeit. Formel-Ergebnisse
bekommen **kein** automatisches Zellformat (wie bei jeder anderen Formel
auch) — das Zahlenformat-Dropdown auf „Datum"/„Zeit"/„Datum + Zeit" stellen.
bekommen **kein** automatisches Zellformat — das Zahlenformat-Dropdown auf
„Datum"/„Zeit"/„Datum + Zeit" stellen. Einzige Ausnahme: eine Formel, deren
Zahlen-Eingaben **alle Zeiten oder Dauern** sind (`=SUM(B2:B8)` über
Arbeitszeiten, `=C2-B2` für Ende − Beginn), zeigt ihr Ergebnis als
**Dauer**, solange die Zelle auf „Automatisch" steht.
`TODAY`/`NOW` sind **nicht volatil**: diese Engine rechnet rein
vorgänger-getrieben neu, ohne Timer — eine Zelle mit `=TODAY()`
aktualisiert sich erst bei ihrer eigenen nächsten Neuberechnung, nicht von
selbst beim Tageswechsel (siehe „Bekannte Grenzen" unten).
Das Zahlenformat **„Dauer"** zählt Stunden über 24 hinaus weiter (`37:30`
statt `13:30`) — für Summen von Arbeits- oder Laufzeiten; Sekunden
erscheinen nur, wenn welche da sind (`100:00:30`). **„Zeit"** bleibt eine
Uhrzeit und springt nach 24 Stunden wieder auf `00:00`. **„Datum + Zeit"**
zeigt bei einer reinen Uhrzeit (unter einem Tag) nur die Uhrzeit statt des
Nullpunkts 30.12.1899.
**Datums- und Zeitfunktionen**: `YEAR`/`MONTH`/`DAY`/`HOUR`/`MINUTE`/`SECOND`
lesen einen Teil aus (auf ganze Sekunden gerundet). Wo Excel eine
US-Voreinstellung hat, gilt hier **ISO 8601**: `WEEKDAY(Datum; [Typ])`
zählt Montag = 1 … Sonntag = 7 (Typ 1: Sonntag = 1, Typ 3: Montag = 0),
`ISOWEEKNUM` und `WEEKNUM(Datum; [Typ])` liefern die ISO-Kalenderwoche
(`WEEKNUM` Typ 1/2: US-Zählung mit Wochenbeginn Sonntag/Montag).
`EDATE(Datum; Monate)` verschiebt um Monate (31.01. + 1 = 28./29.02.),
`EOMONTH(Datum; Monate)` liefert den Monatsletzten, `DAYS(Ende; Start)` die
Kalendertage dazwischen, `DATEDIF(Start; Ende; Einheit)` den Abstand in
`"Y"`/`"M"`/`"D"` bzw. als Rest `"YM"`/`"MD"`/`"YD"`.
`NETWORKDAYS(Start; Ende; [Feiertage])` zählt Arbeitstage (Mo–Fr, beide
Enden eingeschlossen), `WORKDAY(Start; Tage; [Feiertage])` rechnet eine
Frist in Arbeitstagen — Feiertage als Zellen/Bereich. `DATEVALUE(Text)` und
`TIMEVALUE(Text)` lesen Datum bzw. Uhrzeit aus einem Text in jedem Format,
das auch beim Eintippen erkannt wird. Ungültige Argumente ergeben `#VALUE!`.
Das Zahlenformat **„Datum (ISO)"** zeigt ein Datum immer als `JJJJ-MM-TT`
(`2026-09-02`) — unabhängig von der aktiven Locale (Blatt/Dokument oder
Zelle), anders als „Datum", das der jeweiligen Locale folgt (`02.09.2026`
@@ -1082,7 +1112,7 @@ Grundrechenarten: `Übersicht!B2 = =SUM(Umsatz!B2:E2)`, `D2 = =B2-C2`,
## Tests
`npm run test` — Vitest, 528 Tests:
`npm run test` — Vitest, 553 Tests:
- **lexer / parser** — Präzedenz & Assoziativität (`^` vor `*/` vor `+-`, `^`
rechts, `-2^2 = -(2^2)`), lokale/qualifizierte/quoted Bezüge, `!` **und** `::`,
@@ -1404,7 +1434,10 @@ Grundrechenarten: `Übersicht!B2 = =SUM(Umsatz!B2:E2)`, `D2 = =B2-C2`,
und Punkt-Daten, absichtlich **nicht** Schrägstrich-Daten (Tag-zuerst vs.
Monat-zuerst ist über die unterstützten Locales nicht eindeutig auflösbar,
s. o.). Formel-Ergebnisse (`=DATE(...)`, `=TODAY()`, `=A1+30`) bekommen kein
automatisches Zellformat — wie jedes andere Formelergebnis auch. `TODAY()`/
automatisches Zellformat — außer „Dauer" für Formeln über reine Zeiten.
Das gilt auch dann, wenn die Formel die Zeiten in Stunden umrechnet
(`=A1*24`); dort das Format „Automatisch" durch „Ohne Formatierung" o. ä.
ersetzen. `TODAY()`/
`NOW()` sind nicht volatil: sie aktualisieren sich erst bei der nächsten
Neuberechnung ihrer eigenen Zelle, nicht spontan mit der Zeit.
- **XLOOKUP** bewusst ohne: Näherungsvergleich (`Vergleichsmodus` -1/1) auf