principle-i18nlisted
Install: claude install-skill lugassawan/swe-workbench
# Internationalization & Localization Principles
i18n bugs are latent — they survive review unnoticed and only surface when the product expands to a new locale.
## Locale-Aware Formatting
*Use platform APIs that accept a locale tag; never hand-roll date or number rendering.*
- Use `Intl.DateTimeFormat(locale, options)` and `Intl.NumberFormat(locale, options)` — not `Date.toString()`, `toLocaleDateString()` without a locale argument, or manual template strings.
- Pass BCP 47 locale tags (`en-US`, `fr-FR`, `ar-EG`); rely on CLDR data in the runtime rather than custom format maps.
- Never hard-code `MM/DD/YYYY` — format order, separator, and calendar system (Gregorian vs. Hijri vs. Buddhist Era) vary by locale.
- Currency: let `Intl.NumberFormat(locale, { style: 'currency', currency: 'USD' })` place the symbol and decide sign position — never concatenate `"$" + amount`.
- For backend rendering, thread the `Accept-Language` header or a persisted locale preference down to the formatting layer.
## Time Zones: Persist UTC, Render Local
*Timestamps recorded in local time become ambiguous at DST boundaries and when users cross time zones.*
- Persist all timestamps as `TIMESTAMP WITH TIME ZONE` in UTC in the database; never persist local time without an offset.
- Convert to the user's local zone at the display edge (UI component or API response serialiser), not in business logic or queries.
- Account for DST gaps and folds: `America/New_York` can produce two instants for the sam