Files
suaveplan/packages/foundation/timing/datetime/README.md
2026-05-27 23:47:53 +01:00

93 lines
13 KiB
Markdown

# @suaveplan/datetime - Timezone-aware date/time utilities with business-day arithmetic, recurrence rules, calendar math, and relative time formatting
## Summary
Timezone-aware date/time utilities covering the most common application-layer date operations that the native `Date` API leaves unaddressed. The package provides calendar math (`addDuration`, `subtractDuration`, `startOf`, `endOf`, `getCalendarMonth`, leap-year detection), business-day arithmetic with configurable holiday calendars and custom weekend definitions, an RRULE-subset recurrence engine (DAILY/WEEKLY/MONTHLY/YEARLY with BYDAY/BYMONTH/COUNT/UNTIL), and human-readable relative time formatting (`"3 hours ago"`, `"in 2 days"`). All stateful entry points accept an injectable `Clock` for deterministic testing. Use this package for scheduling UIs, calendar components, invoice date calculations, and any domain where "next business day" or "every other Monday" has real meaning. For low-level stopwatches, throttle/debounce, or vector clocks use `@suaveplan/timing`.
<!-- begin:auto-docs -->
## Documentation tree
- [business-days](./src/business-days/business-days.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [business-days](./src/business-days/business-days.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [calendar](./src/calendar/calendar.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [calendar-boundary](./src/calendar/calendar-boundary.md) — `calendar-boundary` provides `startOf` and `endOf` functions for `@suaveplan/datetime`, computing the precise first and…
- [calendar-core](./src/calendar/calendar-core.md) — `calendar-core` provides the foundational date primitives for `@suaveplan/datetime`: coercing heterogeneous `DateInput`…
- [calendar-duration](./src/calendar/calendar-duration.md) — `calendar-duration` provides duration arithmetic for `@suaveplan/datetime`: adding and subtracting `Duration` bags from…
- [calendar-grid](./src/calendar/calendar-grid.md) — `calendar-grid` provides `getCalendarMonth`, which builds a full calendar month grid for use in UI calendar components…
- [calendar](./src/calendar/calendar.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [errors](./src/errors/datetime-error.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [datetime-error](./src/errors/datetime-error.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [otel](./src/otel/datetime-otel.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [datetime-otel](./src/otel/datetime-otel.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [recurrence](./src/recurrence/recurrence.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [recurrence-generate](./src/recurrence/recurrence-generate.md) — `recurrence-generate` provides the internal generator functions that produce infinite sequences of candidate dates for…
- [recurrence-helpers](./src/recurrence/recurrence-helpers.md) — `recurrence-helpers` provides the internal constants and low-level date arithmetic utilities shared across the recurren…
- [recurrence](./src/recurrence/recurrence.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [relative](./src/relative/relative.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [relative](./src/relative/relative.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
<!-- end:auto-docs --> - [business-days](./src/business-days/business-days.md) — <!-- begin:auto-docs --> _(no submodules)_- [calendar](./src/calendar/calendar.md) — <!-- begin:auto-docs --> _(no submodules)_- [calendar-boundary](./src/calendar/calendar-boundary.md) — `calendar-boundary` provides `startOf` and `endOf` functions for `@suaveplan/datetime`, computing the precise first and…
- [calendar-core](./src/calendar/calendar-core.md) — `calendar-core` provides the foundational date primitives for `@suaveplan/datetime`: coercing heterogeneous `DateInput`…
- [calendar-duration](./src/calendar/calendar-duration.md) — `calendar-duration` provides duration arithmetic for `@suaveplan/datetime`: adding and subtracting `Duration` bags from…
- [calendar-grid](./src/calendar/calendar-grid.md) — `calendar-grid` provides `getCalendarMonth`, which builds a full calendar month grid for use in UI calendar components…
- [calendar](./src/calendar/calendar.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/datetime-error.md) — <!-- begin:auto-docs --> _(no submodules)_- [datetime-error](./src/errors/datetime-error.md) — <!-- begin:auto-docs --> _(no submodules)_- [otel](./src/otel/datetime-otel.md) — <!-- begin:auto-docs --> _(no submodules)_- [datetime-otel](./src/otel/datetime-otel.md) — <!-- begin:auto-docs --> _(no submodules)_- [recurrence](./src/recurrence/recurrence.md) — <!-- begin:auto-docs --> _(no submodules)_- [recurrence-generate](./src/recurrence/recurrence-generate.md) — `recurrence-generate` provides the internal generator functions that produce infinite sequences of candidate dates for…
- [recurrence-helpers](./src/recurrence/recurrence-helpers.md) — `recurrence-helpers` provides the internal constants and low-level date arithmetic utilities shared across the recurren…
- [recurrence](./src/recurrence/recurrence.md) — <!-- begin:auto-docs --> _(no submodules)_- [relative](./src/relative/relative.md) — <!-- begin:auto-docs --> _(no submodules)_- [relative](./src/relative/relative.md) — <!-- begin:auto-docs --> _(no submodules)_- [business-days](./src/business-days/business-days.md) — <!-- begin:auto-docs --> _(no submodules)_- [calendar](./src/calendar/calendar.md) — <!-- begin:auto-docs --> _(no submodules)_- [calendar-boundary](./src/calendar/calendar-boundary.md) — `calendar-boundary` provides `startOf` and `endOf` functions for `@suaveplan/datetime`, computing the precise first and…
- [calendar-core](./src/calendar/calendar-core.md) — `calendar-core` provides the foundational date primitives for `@suaveplan/datetime`: coercing heterogeneous `DateInput`…
- [calendar-duration](./src/calendar/calendar-duration.md) — `calendar-duration` provides duration arithmetic for `@suaveplan/datetime`: adding and subtracting `Duration` bags from…
- [calendar-grid](./src/calendar/calendar-grid.md) — `calendar-grid` provides `getCalendarMonth`, which builds a full calendar month grid for use in UI calendar components…
- [calendar](./src/calendar/calendar.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/datetime-error.md) — <!-- begin:auto-docs --> _(no submodules)_- [datetime-error](./src/errors/datetime-error.md) — <!-- begin:auto-docs --> _(no submodules)_- [otel](./src/otel/datetime-otel.md) — <!-- begin:auto-docs --> _(no submodules)_- [datetime-otel](./src/otel/datetime-otel.md) — <!-- begin:auto-docs --> _(no submodules)_- [recurrence](./src/recurrence/recurrence.md) — <!-- begin:auto-docs --> _(no submodules)_- [recurrence-generate](./src/recurrence/recurrence-generate.md) — `recurrence-generate` provides the internal generator functions that produce infinite sequences of candidate dates for…
- [recurrence-helpers](./src/recurrence/recurrence-helpers.md) — `recurrence-helpers` provides the internal constants and low-level date arithmetic utilities shared across the recurren…
- [recurrence](./src/recurrence/recurrence.md) — <!-- begin:auto-docs --> _(no submodules)_- [relative](./src/relative/relative.md) — <!-- begin:auto-docs --> _(no submodules)_- [relative](./src/relative/relative.md) — <!-- begin:auto-docs --> _(no submodules)_- [business-days](./src/business-days/business-days.md) — <!-- begin:auto-docs --> _(no submodules)_- [calendar](./src/calendar/calendar.md) — <!-- begin:auto-docs --> _(no submodules)_- [calendar-boundary](./src/calendar/calendar-boundary.md) — `calendar-boundary` provides `startOf` and `endOf` functions for `@suaveplan/datetime`, computing the precise first and…
- [calendar-core](./src/calendar/calendar-core.md) — `calendar-core` provides the foundational date primitives for `@suaveplan/datetime`: coercing heterogeneous `DateInput`…
- [calendar-duration](./src/calendar/calendar-duration.md) — `calendar-duration` provides duration arithmetic for `@suaveplan/datetime`: adding and subtracting `Duration` bags from…
- [calendar-grid](./src/calendar/calendar-grid.md) — `calendar-grid` provides `getCalendarMonth`, which builds a full calendar month grid for use in UI calendar components…
- [calendar](./src/calendar/calendar.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/datetime-error.md) — <!-- begin:auto-docs --> _(no submodules)_- [datetime-error](./src/errors/datetime-error.md) — <!-- begin:auto-docs --> _(no submodules)_- [otel](./src/otel/datetime-otel.md) — <!-- begin:auto-docs --> _(no submodules)_- [datetime-otel](./src/otel/datetime-otel.md) — <!-- begin:auto-docs --> _(no submodules)_- [recurrence](./src/recurrence/recurrence.md) — <!-- begin:auto-docs --> _(no submodules)_- [recurrence-generate](./src/recurrence/recurrence-generate.md) — `recurrence-generate` provides the internal generator functions that produce infinite sequences of candidate dates for…
- [recurrence-helpers](./src/recurrence/recurrence-helpers.md) — `recurrence-helpers` provides the internal constants and low-level date arithmetic utilities shared across the recurren…
- [recurrence](./src/recurrence/recurrence.md) — <!-- begin:auto-docs --> _(no submodules)_- [relative](./src/relative/relative.md) — <!-- begin:auto-docs --> _(no submodules)_- [relative](./src/relative/relative.md) — <!-- begin:auto-docs --> _(no submodules)_- [business-days](./src/business-days/business-days.md) — <!-- begin:auto-docs --> _(no submodules)_- [calendar](./src/calendar/calendar.md) — <!-- begin:auto-docs --> _(no submodules)_ - [calendar-boundary](./src/calendar/calendar-boundary.md) — `calendar-boundary` provides `startOf` and `endOf` functions for `@suaveplan/datetime`, computing the precise first and…
- [calendar-core](./src/calendar/calendar-core.md) — `calendar-core` provides the foundational date primitives for `@suaveplan/datetime`: coercing heterogeneous `DateInput`…
- [calendar-duration](./src/calendar/calendar-duration.md) — `calendar-duration` provides duration arithmetic for `@suaveplan/datetime`: adding and subtracting `Duration` bags from…
- [calendar-grid](./src/calendar/calendar-grid.md) — `calendar-grid` provides `getCalendarMonth`, which builds a full calendar month grid for use in UI calendar components…
- [calendar](./src/calendar/calendar.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/datetime-error.md) — <!-- begin:auto-docs --> _(no submodules)_ - [datetime-error](./src/errors/datetime-error.md) — <!-- begin:auto-docs --> _(no submodules)_- [otel](./src/otel/datetime-otel.md) — <!-- begin:auto-docs --> _(no submodules)_ - [datetime-otel](./src/otel/datetime-otel.md) — <!-- begin:auto-docs --> _(no submodules)_- [recurrence](./src/recurrence/recurrence.md) — <!-- begin:auto-docs --> _(no submodules)_ - [recurrence-generate](./src/recurrence/recurrence-generate.md) — `recurrence-generate` provides the internal generator functions that produce infinite sequences of candidate dates for…
- [recurrence-helpers](./src/recurrence/recurrence-helpers.md) — `recurrence-helpers` provides the internal constants and low-level date arithmetic utilities shared across the recurren…
- [recurrence](./src/recurrence/recurrence.md) — <!-- begin:auto-docs --> _(no submodules)_- [relative](./src/relative/relative.md) — <!-- begin:auto-docs --> _(no submodules)_ - [relative](./src/relative/relative.md) — <!-- begin:auto-docs --> _(no submodules)_
## Modules
| Module | Description |
|---|---|
| [`calendar`](src/calendar/calendar.md) | Core date arithmetic: `toDate`, `addDuration`, `subtractDuration`, `startOf`, `endOf`, `getCalendarMonth`, `daysInMonth`, `isLeapYear`, `isSameDay`, `isSameMonth` |
| [`business-days`](src/business-days/business-days.md) | Working-day arithmetic with holiday and custom-weekend support |
| [`recurrence`](src/recurrence/recurrence.md) | RRULE parse/format/expand engine (DAILY/WEEKLY/MONTHLY/YEARLY) |
| [`relative`](src/relative/relative.md) | Human-readable relative time: `formatRelative`, `timeAgo`, `timeUntil`, `diffInUnits` |
| [`errors`](src/errors/datetime-error.md) | `DatetimeError` + `DATETIME_CODES` registry |
| [`otel`](src/otel/datetime-otel.md) | OpenTelemetry histogram and counter instrumentation |
## Quick start
```ts
import { addDuration, getCalendarMonth, businessDaysBetween, expandRecurrence, parseRRule, formatRelative } from "@suaveplan/datetime";
// Calendar math
const nextMonth = addDuration(new Date(), { months: 1 });
const march2024 = getCalendarMonth(2024, 3);
// Business days
const tradingDays = businessDaysBetween("2024-01-01", "2024-04-01");
// Recurrence
const meetings = expandRecurrence(parseRRule("FREQ=WEEKLY;BYDAY=MO,WE;COUNT=8"));
// Relative time
console.log(formatRelative(new Date(Date.now() - 3 * 3600_000))); // "3 hours ago"
```
## Installation
```bash
bun add @suaveplan/datetime
```
## License
MIT