Skip to content

[Due for payment 2026-09-25] [Intl] CONST.DATE display formats hardcode US date and time conventions #98088

Description

@shubham1206agra

Problem

Most display-oriented format strings in CONST.DATE (src/CONST/index.ts) are written as explicit date-fns patterns that encode US English conventions — month-before-day ordering, comma separators, and a 12-hour clock. Because the pattern itself fixes the ordering, the output stays in US form in every locale; only the individual words (month names, AM/PM markers) get translated.

The result is text that looks translated but reads as broken in every non-English locale, e.g. German users see Januar 22, 2026 where the correct form is 22. Januar 2026.

date-fns already exposes localized format tokens (P, PP, PPP, PPPP for dates, p/pp for times) that resolve to each locale's own ordering and separators. The affected constants should use those instead of hand-written patterns.

Affected constants

Constant Current pattern Suggested
MONTH_DAY_YEAR_FORMAT MMMM d, yyyy PPP
MONTH_DAY_YEAR_ABBR_FORMAT MMM d, yyyy PP
LONG_DATE_FORMAT_WITH_WEEKDAY eeee, MMMM d, yyyy PPPP
LOCAL_TIME_FORMAT h:mm a p
MONTH_DAY_YEAR_ORDINAL_FORMAT MMMM do, yyyy no direct token (see notes)
MONTH_DAY_ABBR_FORMAT MMM d no direct token (see notes)
SHORT_DATE_FORMAT MM-dd no direct token (see notes)

Evidence

Rendered with date-fns for 2026-01-22 14:05.

Date ordering

MONTH_DAY_YEAR_FORMAT — current MMMM d, yyyy vs localized PPP:

        current                       localized
en      January 22, 2026              22 January 2026
es      enero 22, 2026                22 de enero de 2026
fr      janvier 22, 2026              22 janvier 2026
de      Januar 22, 2026               22. Januar 2026
it      gennaio 22, 2026              22 gennaio 2026
ja      1月 22, 2026                   2026年1月22日
nl      januari 22, 2026              22 januari 2026
pl      stycznia 22, 2026             22 stycznia 2026

LONG_DATE_FORMAT_WITH_WEEKDAY — current eeee, MMMM d, yyyy vs localized PPPP:

        current                       localized
en      Thursday, January 22, 2026    Thursday, 22 January 2026
es      jueves, enero 22, 2026        jueves, 22 de enero de 2026
de      Donnerstag, Januar 22, 2026   Donnerstag, 22. Januar 2026
ja      木曜日, 1月 22, 2026             2026年1月22日木曜日
pl      czwartek, stycznia 22, 2026   czwartek, 22 stycznia 2026

Japanese shows why a hand-written pattern cannot be made correct by reordering tokens: the localized form is 2026年1月22日, with the year first and a character suffix after each component. The abbreviated form is 2026/01/22, a completely different shape again.

Spanish is a second example — it requires the preposition de between components (22 de enero de 2026), which no MMMM d, yyyy-style pattern can produce.

Time format

LOCAL_TIME_FORMAT — current h:mm a vs localized p:

        current          localized
en      2:05 PM          14:05
es      2:05 PM          14:05
fr      2:05 PM          14:05
de      2:05 nachm.      14:05
it      2:05 PM          14:05
ja      2:05 午後          14:05
nl      2:05 PM          14:05
pl      2:05 PM          14:05

This is the highest-impact item. A 12-hour clock is imposed on every locale, while all eight tested locales use a 24-hour clock. The AM/PM marker is translated (German nachm., Japanese 午後), which makes the output look deliberate, but the underlying clock convention is wrong. It appears anywhere a time-of-day is rendered.

Not affected

These are machine formats used for storage, API payloads, or lookup keys, and must stay fixed:

  • FNS_FORMAT_STRING (yyyy-MM-dd)
  • FNS_DATE_TIME_FORMAT_STRING (yyyy-MM-dd HH:mm:ss)
  • FNS_TIMEZONE_FORMAT_STRING (yyyy-MM-dd'T'HH:mm:ssXXX)
  • FNS_DB_FORMAT_STRING (yyyy-MM-dd HH:mm:ss.SSS)
  • YEAR_MONTH_FORMAT (yyyyMM)

These are single tokens, so date-fns already localizes them correctly and no change is needed:

  • MONTH_FORMAT (MMMM)
  • WEEKDAY_TIME_FORMAT (eeee)
  • ORDINAL_DAY_OF_MONTH (do)

SECONDS_PER_DAY and MONTH_DAYS are not format strings.

Caveat: en is mapped to en-GB

IntlStore loads date-fns/locale/en-GB for the en locale, not en-US. Because the current constants are explicit patterns, that mapping has no visible effect today.

Switching to localized tokens would make it visible immediately:

en   current: January 22, 2026      with PPP: 22 January 2026

So adopting PPP/PP/PPPP also changes English output to British ordering. If US ordering is intended for en, the date-fns locale mapping must be changed to enUS first. Otherwise this work silently converts English dates to British format, which is likely to be reported as a regression.

This should be decided before any of the constants change.

Notes on the three constants with no direct token

  • MONTH_DAY_YEAR_ORDINAL_FORMAT (MMMM do, yyyy) — PPP is the closest localized equivalent but drops the ordinal day. Note that date-fns' do output varies in quality across locales (pl and it return a bare number with no ordinal marker), so the ordinal may not be worth preserving in non-English locales.
  • MONTH_DAY_ABBR_FORMAT (MMM d) and SHORT_DATE_FORMAT (MM-dd) — no date-fns localized token covers a month/day pair without a year. Intl.DateTimeFormat(locale, {month: 'short', day: 'numeric'}) produces the correct per-locale ordering for these.

Suggested approach

  1. Decide the enen-US vs en-GB question first, since it gates the visible outcome for the largest locale.
  2. Replace the four constants that have direct equivalents with PPP, PP, PPPP and p.
  3. Replace the remaining three with Intl.DateTimeFormat-based helpers.
  4. Audit call sites: some may be passing these constants to functions that assume a fixed-width or fixed-order output (for example, string parsing or column alignment).

Verification

For each affected constant, render a fixed date across all supported locales and confirm the output matches the locale's conventional form:

const {format} = require('date-fns');
const d = new Date(2026, 0, 22, 14, 5);
format(d, 'PPP', {locale}); // etc.
Issue OwnerCurrent Issue Owner: @linhvovan29546

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions