localDay.ts

Converts dates to and from local-timezone day keys and computes day differences

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 Date or date string to a local-timezone day key string
  • Parsing a day key string back to a Date representing 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: throws Error("Invalid local day input") for non-parseable inputs
  • localDayKeyToDate: throws Error("Invalid local day key: ...") for malformed or calendar-invalid keys
  • diffLocalDayKeys: inherits both; delegates to localDayKeyToDate for 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.