first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,112 @@
# Day / Month names
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
`getDayNames(locale, style?)` and `getMonthNames(locale, style?)`
return the locale-correct list of weekday or month names. They are
the canonical primitives for day-picker / calendar / date-picker UI
components — every locale wants a different starting weekday and a
different rendering style.
`getDayNames` consults `Intl.Locale.getWeekInfo()` (ECMA-402 §10.6) to
discover the locale-defined first day of the week (1 = Monday … 7 =
Sunday). When the host runtime lacks `getWeekInfo` (older Node, older
browsers), the function falls back to Monday-start.
## Features
- `getDayNames(locale, style?)` returns 7 strings starting from the locale's first weekday
- `getMonthNames(locale, style?)` returns 12 strings
- Both accept `"long"` (default), `"short"`, or `"narrow"` style
- BCP-47 normalisation through `LOCALE_BCP47_MAP`
- `getDayNames` falls back to Monday-start when `getWeekInfo` is unavailable or throws
- Pure functions — no shared state, no cache
## Usage: Basic Example
```ts
import {
getDayNames,
getMonthNames,
} from "@suaveplan/i18n-formatter-date";
getDayNames("en-GB");
// ["Monday", "Tuesday", ..., "Sunday"]
getDayNames("en-US", "short");
// ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
getMonthNames("en-GB");
// ["January", "February", ..., "December"]
getMonthNames("fr-FR", "narrow");
// ["J", "F", "M", "A", "M", "J", "J", "A", "S", "O", "N", "D"]
```
## Usage: Advanced Example
```ts
import {
getDayNames,
getMonthNames,
} from "@suaveplan/i18n-formatter-date";
// Build a date-picker header that respects the user's locale.
function renderCalendarHeader(locale: string) {
const days = getDayNames(locale, "narrow");
const months = getMonthNames(locale, "long");
return { days, months };
}
const header = renderCalendarHeader("ja-JP");
// header.days[0] is the locale-correct first weekday name
// header.months is the 12 long Japanese month names
// Stub Intl.Locale.getWeekInfo to test the Monday-start fallback.
const Original = Intl.Locale;
Intl.Locale = function () {
return { getWeekInfo: undefined } as unknown as Intl.Locale;
} as unknown as typeof Intl.Locale;
try {
const days = getDayNames("en-US"); // falls back to Monday-start
console.log(days[0]); // "Monday"
} finally {
Intl.Locale = Original;
}
```
## API Reference
### `getDayNames(locale, style?): string[]`
- `locale` — BCP-47 locale tag.
- `style` — `"long"` (default), `"short"`, or `"narrow"`.
- Returns 7 strings starting from the locale-defined first weekday.
- Anchors on Monday 2024-01-01 then offsets by `(firstDay - 1)` so
index 0 is the locale's first weekday.
### `getMonthNames(locale, style?): string[]`
- `locale` — BCP-47 locale tag.
- `style` — `"long"` (default), `"short"`, or `"narrow"`.
- Returns 12 strings, one per month.
## Implementation Notes
- The `getWeekInfo()` probe is wrapped in `try/catch` because (a)
older runtimes don't expose the method at all (the access throws
`TypeError`), and (b) some older proposals exposed `weekInfo` as a
property — neither path is hit on current Node/Bun/browser, but the
fallback keeps the function safe across the entire range.
- The constants are computed by iterating dates through
`Intl.DateTimeFormat`, not by hard-coding day/month strings —
that's what makes the helpers correctly return localised names for
every BCP-47 tag without a translation table.
- These helpers do NOT participate in the formatter cache because
they construct ad-hoc `Intl.DateTimeFormat` instances per call.
The cost is negligible (single-digit microseconds) and avoids
mixing weekday-style cache entries with the main formatter cache.