129 lines
6.2 KiB
Markdown
129 lines
6.2 KiB
Markdown
# @suaveplan/i18n-formatter-date - Intl.DateTimeFormat wrapper for the @suaveplan/i18n family — 8-preset table (short/medium/long/full/time-short/time-long/date-short/date-long), formatDate / formatTime / formatDateOnly / formatDateRange / getDayNames / getMonthNames. Per-(locale, options-hash) cache, Zod-validated options, OTel histogram + cache-hit counter, structured I18nError mapping. Universal leaf package.
|
||
|
||
## Summary
|
||
|
||
Wrapper around `Intl.DateTimeFormat` for the `@suaveplan/i18n` family
|
||
— 8-preset table (short/medium/long/full × date+time/time-only/date-only),
|
||
range rendering, day/month name lists, and a per-(locale,
|
||
options-hash) cache.
|
||
|
||
<!-- begin:auto-docs -->
|
||
## Documentation tree
|
||
|
||
- [day-month-names](./src/day-month-names/day-month-names.md) — `getDayNames(locale, style?)` and `getMonthNames(locale, style?)` return the locale-correct list of weekday or month na…
|
||
- [day-month-names](./src/day-month-names/day-month-names.md) — `getDayNames(locale, style?)` and `getMonthNames(locale, style?)` return the locale-correct list of weekday or month na…
|
||
- [formatter](./src/formatter/formatter.md) — `DateFormatter` and the `formatDate` / `formatDateRange` standalone helpers expose `Intl.DateTimeFormat` for the `@suav…
|
||
- [formatter](./src/formatter/formatter.md) — `DateFormatter` and the `formatDate` / `formatDateRange` standalone helpers expose `Intl.DateTimeFormat` for the `@suav…
|
||
- [helpers](./src/helpers/helpers.md) — `formatTime` and `formatDateOnly` pre-bind `formatDate` with the appropriate preset for time-only or date-only renderin…
|
||
- [helpers](./src/helpers/helpers.md) — `formatTime` and `formatDateOnly` pre-bind `formatDate` with the appropriate preset for time-only or date-only renderin…
|
||
- [observability](./src/observability/observability.md) — The Date formatter exports two OpenTelemetry instruments and a small in-memory state ring so spec-conformance tests can…
|
||
- [observability](./src/observability/observability.md) — The Date formatter exports two OpenTelemetry instruments and a small in-memory state ring so spec-conformance tests can…
|
||
- [presets](./src/presets/presets.md) — `PRESET_MAP` is the canonical 8-entry table that maps each `DateFormatPreset` discriminant to a concrete `Intl.DateTime…
|
||
- [presets](./src/presets/presets.md) — `PRESET_MAP` is the canonical 8-entry table that maps each `DateFormatPreset` discriminant to a concrete `Intl.DateTime…
|
||
<!-- end:auto-docs -->
|
||
|
||
## Why this exists
|
||
|
||
The 14-package i18n modular split (cross-cutting design
|
||
`2026-05-05-i18n-modular-split.md`) lifts each `Intl.*` wrapper out
|
||
of the monolith into its own sibling package. Lifting the date
|
||
helper out of `@suaveplan/i18n` lets consumers that only need
|
||
date/time rendering (most UI consumers) pull a single small package
|
||
instead of the entire i18n core.
|
||
|
||
The package adds the canonical Wave-3 formatter shape on top of the
|
||
monolith's standalone helpers: Zod-validated options, a per-(locale,
|
||
options-hash) cache, OTel histogram + cache-hit counter, and the
|
||
`DateFormatter` class wrapper for symmetry with `NumberFormatter` /
|
||
`RelativeTimeFormatter` / `ListFormatter` / `DisplayNameFormatter`.
|
||
|
||
## Install
|
||
|
||
```bash
|
||
bun add @suaveplan/i18n-formatter-date
|
||
```
|
||
|
||
## Quick Start
|
||
|
||
```ts
|
||
import {
|
||
DateFormatter,
|
||
formatDate,
|
||
formatDateOnly,
|
||
formatDateRange,
|
||
formatTime,
|
||
getDayNames,
|
||
getMonthNames,
|
||
} from "@suaveplan/i18n-formatter-date";
|
||
|
||
const now = new Date(2026, 0, 1, 14, 30, 45);
|
||
|
||
formatDate(now, "en-GB", { preset: "short" }); // "01/01/2026, 14:30"
|
||
formatTime(now, "en-GB", true); // "14:30:45"
|
||
formatDateOnly(now, "en-GB", true); // "1 January 2026"
|
||
|
||
formatDateRange(
|
||
new Date(2026, 0, 1),
|
||
new Date(2026, 0, 5),
|
||
"en-GB",
|
||
{ day: "numeric", month: "long" }
|
||
); // "1 – 5 January"
|
||
|
||
getDayNames("en-GB", "short");
|
||
// ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
|
||
|
||
const f = new DateFormatter({ preset: "long", timeZone: "Europe/London" });
|
||
f.format(now, "en-GB");
|
||
```
|
||
|
||
## Modules
|
||
|
||
| Subpath | Description |
|
||
|---|---|
|
||
| `@suaveplan/i18n-formatter-date` | Root barrel — class + standalones + helpers + presets + day/month names |
|
||
| `@suaveplan/i18n-formatter-date/formatter` | `DateFormatter`, `formatDate`, `formatDateRange`, `toBcp47`, types, schema |
|
||
| `@suaveplan/i18n-formatter-date/helpers` | `formatTime`, `formatDateOnly` |
|
||
| `@suaveplan/i18n-formatter-date/presets` | `PRESET_MAP`, `DATE_FORMAT_PRESETS`, `resolvePreset` |
|
||
| `@suaveplan/i18n-formatter-date/day-month-names` | `getDayNames`, `getMonthNames` |
|
||
|
||
## Modules Documentation
|
||
|
||
- [formatter.md](src/formatter.md) — `DateFormatter`, `formatDate`, `formatDateRange`, `toBcp47`, `clearDateFormatterCache`
|
||
- [helpers.md](src/helpers.md) — `formatTime`, `formatDateOnly`
|
||
- [presets.md](src/presets.md) — 8-preset table + `resolvePreset`
|
||
- [day-month-names.md](src/day-month-names.md) — `getDayNames`, `getMonthNames`
|
||
- [observability.md](src/observability.md) — OTel histogram + cache-hit counter
|
||
|
||
## Public Surface (snapshot)
|
||
|
||
| Export | Kind | Origin |
|
||
|---|---|---|
|
||
| `DateFormatter` | class | `formatter.ts` |
|
||
| `formatDate` | function | `formatter.ts` |
|
||
| `formatDateRange` | function | `formatter.ts` |
|
||
| `toBcp47` | function | `formatter.ts` |
|
||
| `clearDateFormatterCache` | function | `formatter.ts` |
|
||
| `DateFormatterOptionsSchema` | Zod schema | `formatter.schemas.ts` |
|
||
| `DateFormatPreset` | type | `formatter.types.ts` |
|
||
| `DateFormatOptions` | type | `formatter.types.ts` |
|
||
| `ExtendedDateOptions` | type | `formatter.types.ts` |
|
||
| `DateFormatterCacheKey` | type | `formatter.types.ts` |
|
||
| `formatTime` | function | `helpers.ts` |
|
||
| `formatDateOnly` | function | `helpers.ts` |
|
||
| `PRESET_MAP` | const | `presets.ts` |
|
||
| `DATE_FORMAT_PRESETS` | const | `presets.ts` |
|
||
| `resolvePreset` | function | `presets.ts` |
|
||
| `PresetTable` | type | `presets.types.ts` |
|
||
| `getDayNames` | function | `day-month-names.ts` |
|
||
| `getMonthNames` | function | `day-month-names.ts` |
|
||
| `recordDateFormat` | function | `observability.ts` |
|
||
| `recordDateCacheHit` | function | `observability.ts` |
|
||
| `getDateMetricsState` | function | `observability.ts` |
|
||
| `resetDateMetricsState` | function | `observability.ts` |
|
||
|
||
## Versioning
|
||
|
||
Part of the 14-package i18n modular-split rollout. Stays at `0.1.0`
|
||
until the slim core (Wave 6) cuts the family `1.0.0` release.
|
||
|