localDay.ts
Purpose
This module provides the canonical local-day key format (YYYY-MM-DD) used throughout the work area store and other date-keyed persistence layers. All operations use the device’s local timezone, not UTC.
Its responsibilities include:
- Converting any
Dateor date string to a local-timezone day key string - Parsing a day key string back to a
Daterepresenting midnight local time - Computing the integer number of calendar days between two day keys
- Validating all inputs and throwing descriptive errors on failure
Invariants
Local Timezone
All Date field accesses use getFullYear(), getMonth(), and getDate() (local timezone), not their UTC equivalents.
This means a timestamp at 2024-07-01T00:30:00Z in UTC-8 produces day key "2024-06-30".
Day Key Format
Keys always match /^\d{4}-\d{2}-\d{2}$/.
localDayKeyToDate validates the format with this pattern and additionally verifies that the constructed Date round-trips correctly (guarding against inputs like "2024-02-30").
Invalid Input Throws
toLocalDayKey: throwsError("Invalid local day input")for non-parseable inputslocalDayKeyToDate: throwsError("Invalid local day key: ...")for malformed or calendar-invalid keysdiffLocalDayKeys: inherits both; delegates tolocalDayKeyToDatefor both arguments
diffLocalDayKeys Rounds
The difference is computed as:
Math.round((later.getTime() - earlier.getTime()) / MS_PER_DAY)
Math.round handles DST boundary crossings (where a day may be 23 or 25 hours) without producing off-by-one errors.
Exports
toLocalDayKey(...)
function toLocalDayKey(input?: Date | string): string
Returns the local-timezone day key for the given date (default: new Date()).
localDayKeyToDate(...)
function localDayKeyToDate(dayKey: string): Date
Parses a YYYY-MM-DD day key into a Date at midnight local time. Throws on invalid format or calendar-invalid dates.
diffLocalDayKeys(...)
function diffLocalDayKeys(laterDayKey: string, earlierDayKey: string): number
Returns the signed integer number of calendar days from earlierDayKey to laterDayKey. Positive when later is after earlier.