Skip to content

feat(Timestamp, PowerSearch, Schedule): write dates in the provider's calendar - #9639

Open
nynexman4464 wants to merge 10 commits into
nynexman4464/feat/calendar-systems-corefrom
nynexman4464/feat/calendar-formatters
Open

nynexman4464 wants to merge 10 commits into
nynexman4464/feat/calendar-systems-corefrom
nynexman4464/feat/calendar-formatters

Conversation

@nynexman4464

@nynexman4464 nynexman4464 commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Base is #9622's branch. Only the formatter commits are in this diff. It retargets to main when #9622 lands.

This implements spec:AST-111 (draft #9605) FR18.

User need

An application that sets calendar="persian" (or hebrew, buddhist, …) on InternationalizationProvider gets Persian dates in Calendar. But a Timestamp, a PowerSearch date token, a Schedule label, or a chart axis beside it still reads Gregorian. One screen then shows the same day in two calendars, so people misread dates.

Problem and solution fit

  • Timestamp: the date, date_long, date_weekday and date_time formats, the hover card's full date, and the relative accessible name use the provider's resolved calendar. time, relative, system_* and unix_seconds don't change.
  • PowerSearch: date values use it. Lab's MobilePowerSearch is left unchanged: main has removed it, and Core's PowerSearch now carries that touch flow.
  • Schedule: titles, day numbers, weekday and full-date labels, week ranges, and long event ranges use it. A Gregorian month that spans two calendar months is titled with both. Grids and stepping stay Gregorian.
  • Pure helpers keep a Gregorian default and take an optional trailing calendar: formatSharedDate, formatFilterValue, and shortDate/monthYear in @astryxdesign/charts and Lab Chart. Astryx's own Timestamp, PowerSearch and Schedule calls pass the resolved calendar.
  • Lab resolves the calendar through a new reserved internal entry, @astryxdesign/core/internal/calendar-system. It applies the same rules and the same no-Temporal fallback as Calendar.

Current specification

  • spec:AST-111 FR18, together with FR2 and FR5.
  • architecture:internationalization INV8–INV10.
  • spec:AST-017 FR21 for the internal entry.
  • spec:AST-013 FR12: Timestamp and PowerSearch record the browser-support exception for calendars that need Temporal (AST-111 FR5), as Calendar and the date inputs do.

Public delta and caller burden

  • No new prop. Without a provider calendar, every output stays the same.
  • Additive arguments, each defaulting to 'gregory': formatSharedDate(pd, format, locale?, calendar?), formatFilterValue(…, timezoneID?, calendar?), shortDate(value, locale, calendar?) and monthYear(value, locale, calendar?).
// before
<InternationalizationProvider locale="en" calendar="persian">
  <Timestamp value={iso} format="date_long" /> {/* October 30, 2026 */}
</InternationalizationProvider>
// after
{/* Aban 8, 1405 AP */}
  • Charts: chart formatters have no provider access and no Astryx call site, so an application passes its calendar itself.

Design and alternatives

Formatting reads the same calendar each date component already resolves, including the fallback to Gregorian without Temporal, so a Timestamp and a Calendar in one subtree show the same calendar. Under chinese and dangi, Timestamp formats that include a time, PowerSearch's date-and-time value and Schedule's week ranges still take the date from Intl, so they can differ by a day where Intl and Temporal disagree; the Timestamp record lists this as an implementation gap.

Rejected: each formatter picking up its locale's default calendar. FR2 excludes that.

Known limit: Schedule's month grid and paging stay Gregorian. Only its labels follow the calendar.

Evidence

Real Chromium against Storybook, in English and fa-IR:

  • Native Temporal: Timestamp, the PowerSearch token and Calendar all show Aban 1405, and system_date_time stays 2026-10-30 12:00:00.
  • Temporal removed: Gregorian dates, plus the development warning.
  • Temporal removed, polyfill loaded: the same as native.

Screenshots

State Screenshot
Chromium, provider calendar="persian", English panel en
Chromium, provider calendar="persian", fa-IR panel fa-IR
Chromium without Temporal: Gregorian fallback no temporal
WebKit (Safari 26.5) with the polyfill webkit

Scope

  • One capability is added.
  • Unrelated fixes, cleanup, and policy changes were removed or split.
  • Consumer docs, focused tests, and migration evidence ship with the feature.
  • Public text and artifacts contain no internal Meta context.

Testing

  • pnpm exec vitest run --project ui over Timestamp, PowerSearch, Calendar, i18n, utils, internal, Lab Schedule, and Chart, and charts: 123 files and 2114 tests pass. DateInput and plainDate: 490 tests pass.
  • Test matrix:
    • persian, hebrew and buddhist, each under en and the native locale;
    • Gregorian defaults, with system_* and time unchanged;
    • the no-Temporal fallback, with buddhist still working;
    • Timestamp under a provider calendar, a -u-ca- locale, and a bare fa-IR.
  • pnpm check:knowledge passes.
  • tsc --noEmit is clean for core, lab and charts, apart from pre-existing pseudo.json import errors that also fail on the base.

Writing rubric results

component:Timestamp:

  • R1 narration: none. FR2 and the compatibility lines describe behavior in the present tense.
  • R2 research: none.
  • R3 evidence: the verification cells name test suites and states, not pull requests. The new AST-013 FR12 exception names its evidence gap.
  • R4 rejected alternatives: none added.
  • R5 change references: none.
  • R6 open questions: none.

component:PowerSearch:

  • R1 narration: none added.
  • R2 research: none.
  • R3 evidence: names a test file, and states the gap (no real-browser or hydration run under a calendar that needs Temporal).
  • R4 rejected alternatives: none.
  • R5 change references: none.
  • R6 open questions: none affected.

@vercel

vercel Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
astryx Ready Ready Preview Nov 3, 2026 10:52pm UTC

Request Review

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Nov 2, 2026
@astracat-bot

astracat-bot Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

AI review status for this pull request.

Review status Updated
❓ Needs maintainer input (for maintainers only) Nov 3, 2026, 11:08 PM UTC

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approval waits on an engineering owner's decision. Built-in date formats that follow the provider's calendar (Timestamp's date formats, PowerSearch values, Schedule labels and the new calendar helper arguments) rest only on the draft spec:AST-111 FR18, while the current internationalization architecture (INV10) and Timestamp FR2 still pin Gregorian. An engineering owner records that decision by commenting /approve-spec <full head SHA> on this pull request; the author may do so if they are an engineering owner. Whatever the decision, these need fixing:

  • Relative Timestamps now fail hydration when the server lacks Temporal but the browser has it (Timestamp.tsx:367, Timestamp FR3); keep the pre-hydration placeholder Gregorian.
  • Schedule's isSameCalendarMonth works out calendar months a second way; re-export Core's calendarMonthOf through the internal entry and call it.
  • The title says charts follow the provider calendar, and the body says Astryx call sites pass the calendar to formatSharedDate; neither is true yet, so narrow the wording.

[Automated review]

isClockPending
? {timeZone: 'UTC', isTimezoneShown: true}
: {isTimezoneShown},
? {timeZone: 'UTC', isTimezoneShown: true, calendar}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With a calendar that needs Temporal, the server and the browser can resolve different calendars here. On a server without Temporal (Node 24) the placeholder is Gregorian; a browser with native Temporal writes it in Persian, and React reports "Hydration failed because the server rendered text didn't match the client". Timestamp FR3 says the server markup hydrates without a mismatch. The client replaces this placeholder after hydration, so keeping it Gregorian ({timeZone: 'UTC', isTimezoneShown: true}) avoids the mismatch.


// A Gregorian month or year can span two months or years of another calendar,
// so ranges compare the calendar's own fields.
function isSameCalendarMonth(

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Core's calendarMonthOf (packages/core/src/utils/calendarSystem.ts) already decides which calendar month a Gregorian day falls in, and Calendar uses it. This string comparison is a second path, and the two already disagree: under japanese, Gregorian January 1989 is one month to Core but two here ("January 64 Shōwa - January 1 Heisei"). Re-export calendarMonthOf from @astryxdesign/core/internal/calendar-system and compare calendarMonthOf(calendar, a).start for both dates.

Comment thread packages/charts/src/formatters.ts Outdated
calendar: 'gregory',
}),
);
/** One date formatter per locale and calendar. */

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking: this comment restates byLocaleAndCalendar. Delete it.

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approval waits on an engineering owner's decision. Built-in date formats that follow the provider's calendar (Timestamp's date formats, its card and accessible name, PowerSearch values, Schedule labels, and the new calendar arguments on formatSharedDate and formatFilterValue) rest only on the draft spec:AST-111 FR18, while the current internationalization architecture (INV10) and Timestamp FR2 still pin Gregorian. An engineering owner records that decision by commenting /approve-spec <full head SHA> on this pull request; the author may do so if they are an engineering owner. Whatever the decision, these need fixing:

  • Relative Timestamps fail hydration when the server lacks Temporal but the browser has it (Timestamp.tsx:367, Timestamp FR3), so keep the pre-hydration placeholder Gregorian and state the both-sides-Temporal condition next to FR3's zone gap.
  • Under chinese and dangi, Timestamp, PowerSearch and Schedule write dates with raw Intl while Calendar uses Core's formatCalendarDate, so Gregorian 2027-02-06 is day 1 of First Month in Calendar but the 30th of Twelfth Month beside it; route these labels, and Schedule's isSameCalendarMonth, through Core's calendar helpers.
  • InternationalizationProvider's docs and record at this head still say the provider calendar reaches only Calendar, so update them to name Timestamp, PowerSearch and Schedule.
  • The title (charts), the body ("Astryx call sites pass the resolved calendar", "always agree") and the changeset's opening sentence claim more than the change does, so narrow them to the components that pass the calendar.

[Automated review]

isClockPending
? {timeZone: 'UTC', isTimezoneShown: true}
: {isTimezoneShown},
? {timeZone: 'UTC', isTimezoneShown: true, calendar}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With a calendar that needs Temporal, a server without it (Node 24) writes this placeholder in Gregorian and a browser with native Temporal writes it in that calendar, so React reports "Hydration failed because the server rendered text didn't match the client" (Timestamp FR3). The client replaces the placeholder after hydration, so keeping it Gregorian ({timeZone: 'UTC', isTimezoneShown: true}) removes the mismatch.


// A Gregorian month or year can span two months or years of another calendar,
// so ranges compare the calendar's own fields.
function isSameCalendarMonth(

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Core's calendarMonthOf and formatCalendarDate (packages/core/src/utils/calendarSystem.ts) already decide calendar months and write a day the way Calendar shows it. This string comparison and the raw-Intl labels are a second path that disagrees: under japanese, Gregorian January 1989 is one month to Calendar and two here, and under chinese, 2027-02-06 is day 1 of First Month in Calendar but day 30 here. Re-export those helpers from @astryxdesign/core/internal/calendar-system and call them.

Comment thread packages/charts/src/formatters.ts Outdated
calendar: 'gregory',
}),
);
/** One date formatter per locale and calendar. */

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking: this comment restates byLocaleAndCalendar; delete it.

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approval waits on an engineering owner's decision. Built-in date formats that follow the provider's calendar (Timestamp's date formats, its hover card and accessible name, PowerSearch values, Schedule labels, and the new calendar arguments on formatSharedDate and formatFilterValue) rest only on the draft spec:AST-111 FR18, which is not on main, while the current internationalization architecture (INV10) and Timestamp FR2 still pin the Gregorian calendar. An engineering owner records that decision by commenting /approve-spec <full head SHA> on this pull request; the author may do so as an engineering owner. Whatever the decision, these need fixing:

  • A server without Temporal fails React hydration in a browser that has it (Timestamp.tsx:367, Timestamp FR3), so keep the pre-hydration placeholder Gregorian and state in the rewritten record that date formats hydrate cleanly only when both sides have Temporal or both lack it.
  • Under chinese and dangi, Timestamp, PowerSearch and Schedule write dates with raw Intl while Calendar uses Core's formatCalendarDate, so with native Temporal Gregorian 2027-02-06 is day 1 of First Month in Calendar but the 30th of Twelfth Month beside it; route these labels, and Schedule's isSameCalendarMonth, through Core's calendar helpers.
  • The InternationalizationProvider docs and prop description still say the calendar is what Calendar shows, so name Timestamp, PowerSearch and Schedule there too.
  • The title includes charts, which never read the provider, and the body says Astryx call sites pass the calendar and that a Timestamp and a Calendar always agree, which formatSharedDate's callers and the Chinese case contradict, so narrow that wording.

[Automated review]

isClockPending
? {timeZone: 'UTC', isTimezoneShown: true}
: {isTimezoneShown},
? {timeZone: 'UTC', isTimezoneShown: true, calendar}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With a calendar that needs Temporal, a server without it (Node 24) writes this placeholder in Gregorian and a browser with native Temporal writes it in that calendar, so React reports "Hydration failed because the server rendered text didn't match the client" (Timestamp FR3). Keep the placeholder Gregorian; the client replaces it after hydration:

isClockPending
  ? {timeZone: 'UTC', isTimezoneShown: true}
  : {isTimezoneShown, calendar},

timeZoneName: timeZoneNameStyle,
...zone,
calendar: 'gregory',
calendar,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Under chinese and dangi, raw Intl and the runtime's Temporal disagree on some month starts, and Calendar names days through Core's formatCalendarDate (utils/calendarSystem.ts), which follows Temporal. With native Temporal, Gregorian 2027-02-06 is day 1 of First Month in Calendar but "Twelfth Month 30, 2026" here. Format the date part through the same helper so the two agree.


// A Gregorian month or year can span two months or years of another calendar,
// so ranges compare the calendar's own fields.
function isSameCalendarMonth(

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Core's calendarMonthOf (packages/core/src/utils/calendarSystem.ts) already decides which calendar month a Gregorian day falls in, and Calendar uses it. This string comparison is a second path that disagrees with it: under japanese, January 1989 is one month to Calendar and two here. Export calendarMonthOf and formatCalendarMonthLabel through @astryxdesign/core/internal/calendar-system and call them instead.

type: "'gregory' | 'iso8601' | 'buddhist' | 'roc' | 'japanese' | 'persian' | 'indian' | 'hebrew' | 'chinese' | 'dangi' | 'coptic' | 'ethiopic' | 'ethioaa' | 'islamic-civil' | 'islamic-tbla' | 'islamic-umalqura'",
required: false,
description:
"Calendar system that `Calendar` in the subtree shows, such as 'persian', 'hebrew', or 'buddhist'. `DateInput`, `DateRangeInput`, and `DateTimeInput` show Gregorian dates. When omitted, a `-u-ca-` keyword in `locale` selects the calendar, else Gregorian; a locale's default calendar never applies. A component's own `calendar` prop takes precedence. Values stay Gregorian ISO dates. Calendars other than gregory, iso8601, buddhist, roc, and japanese need `Temporal`; where the runtime lacks it, load a polyfill such as `temporal-polyfill/full/global` on the server and in the browser, or those calendars show Gregorian dates and warn in development.",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With this pull request the provider calendar also rewrites Timestamp, PowerSearch and Schedule dates, but this description (and the prop JSDoc in InternationalizationProvider.tsx) still says it is the calendar that Calendar shows. Name those components here so builders know what setting calendar changes.

Comment thread packages/charts/src/formatters.ts Outdated
calendar: 'gregory',
}),
);
/** One date formatter per locale and calendar. */

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking: this comment restates byLocaleAndCalendar; delete it.

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approval waits on an engineering owner's decision. Built-in date formats that follow the provider's calendar (Timestamp's date formats, its hover card and accessible name, PowerSearch values, Schedule labels, the switch for existing -u-ca- locales, and the new calendar arguments on formatSharedDate and formatFilterValue) rest only on the draft spec:AST-111 FR18, which is not on main, while the current internationalization architecture (INV10) and Timestamp FR2 still pin the Gregorian calendar. An engineering owner records that decision by commenting /approve-spec <full head SHA> on this pull request; the author may do so as an engineering owner. Whatever the decision, these need fixing:

  • A server without Temporal fails React hydration in a browser that has it (Timestamp.tsx:367, Timestamp FR3), so keep the pre-hydration placeholder Gregorian and state in FR3 that date formats hydrate cleanly only when both sides have Temporal or both lack it.
  • Under chinese and dangi, Timestamp, PowerSearch and Schedule write dates with raw Intl while Calendar uses Core's formatCalendarDate, so with native Temporal Gregorian 2027-02-06 is day 1 of First Month in Calendar but the 30th of Twelfth Month beside it; route these labels, and Schedule's isSameCalendarMonth, through Core's calendar helpers.
  • The InternationalizationProvider docs and prop description still say the calendar is what Calendar shows, so name Timestamp, PowerSearch and Schedule there too.
  • The title includes charts, whose formatters never read the provider, and the body says Astryx call sites pass the calendar to formatSharedDate and that a Timestamp and a Calendar always agree, so narrow that wording.

[Automated review]

@imdreamrunner

Copy link
Copy Markdown
Contributor

Heads-up: #9790 removed packages/lab/src/MobilePowerSearch from main (Core's PowerSearch now ships that touch flow), so the hunks under that directory can be dropped when this rebases.

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approval waits on an engineering owner's decision: built-in date formats that follow the provider's calendar (Timestamp's date formats, its hover card and accessible name, PowerSearch values, Schedule labels, the switch for existing -u-ca- locales, and the new calendar arguments on formatSharedDate and formatFilterValue), together with the new Timestamp FR2/FR3 text and the browser-support exceptions in the Timestamp and PowerSearch records, rest only on the draft spec:AST-111 FR18, which is not on main, while the current internationalization architecture (INV10) and Timestamp FR2 still pin the Gregorian calendar. An engineering owner records that decision by commenting /approve-spec <full head SHA> on this pull request; the author may do so as an engineering owner. Whatever the decision, these need fixing:

  • Under chinese and dangi, Timestamp, PowerSearch and Schedule write dates with raw Intl while Calendar uses Core's formatCalendarDate, so in Chromium with native Temporal Gregorian 2027-02-06 is day 1 of First Month in Calendar but the 30th of Twelfth Month beside it, and Schedule's isSameCalendarMonth splits Gregorian January 1989 under japanese where Core's calendarMonthOf does not; route these labels through Core's calendar helpers.
  • The InternationalizationProvider docs and prop description still say the calendar is what Calendar shows, so name Timestamp, PowerSearch and Schedule there too.
  • The title includes charts, whose formatters never read the provider, and the body says Astryx call sites pass the calendar to formatSharedDate and that a Timestamp and a Calendar always agree, so narrow that wording.

[Automated review]

...SHARED_DATE_FORMAT_OPTIONS.date_long,
...zone,
calendar: 'gregory',
calendar,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Under chinese and dangi, raw Intl and the runtime's Temporal disagree on some month starts, and Calendar names days through Core's formatCalendarDate (utils/calendarSystem.ts), which follows Temporal. In Chromium 149 with native Temporal, Gregorian 2027-02-06 is day 1 of First Month in Calendar but "Twelfth Month 30, 2026" here (and in formatFilterValue.ts). Format the date part through the same helper so the two agree.


// A Gregorian month or year can span two months or years of another calendar,
// so ranges compare the calendar's own fields.
function isSameCalendarMonth(

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Core's calendarMonthOf (packages/core/src/utils/calendarSystem.ts) already decides which calendar month a Gregorian day falls in, and Calendar uses it. This string comparison is a second path that disagrees with it: under japanese, Gregorian January 1989 is one month to Calendar ("January 1 Heisei") and two here ("January 64 Shōwa - January 1 Heisei"). Export calendarMonthOf and formatCalendarMonthLabel through @astryxdesign/core/internal/calendar-system and call them here.

Comment thread packages/charts/src/formatters.ts Outdated
calendar: 'gregory',
}),
);
/** One date formatter per locale and calendar. */

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking: this comment restates byLocaleAndCalendar; delete it.

…calendar

Timestamp's date-bearing formats, its accessible name and hover card rows,
and PowerSearch's date values, including the bottom-sheet presentation's
token, Filters rows, and removal announcement, now use the calendar that the
InternationalizationProvider resolves. The pure formatters take an explicit
calendar that defaults to Gregorian. Time-only, relative, system_* and
unix_seconds output does not change.
Lab components reach Core's calendar resolution through
@astryxdesign/core/internal/calendar-system, so their date labels follow
the same calendar as Core's date components.
Schedule's titles, day numbers, weekday and full-date labels, week ranges,
and long event ranges use the calendar that Core's date components resolve.
A Gregorian month that spans two calendar months is titled with both.
Schedule still lays out and steps Gregorian days, weeks, and months.
The chart date formatters keep a Gregorian default and accept a calendar,
so an application can write axis and tooltip dates in the calendar its
date components use.
The Timestamp record states which formats follow the calendar that the
provider resolves and which stay Gregorian or calendar-neutral. The
Timestamp, PowerSearch, and Schedule docs say the same for builders, the
API report records formatFilterValue's calendar argument, and a Changeset
describes the change.
formatSharedDate keeps its Gregorian default and takes an optional
trailing calendar, so a caller can write the shared date formats in the
calendar its date components use. system_date stays the Gregorian ISO
date.
A Calendar systems story shows Timestamp's date formats, a PowerSearch
date value, and Calendar in the Persian calendar, in English and Farsi,
with system_date_time staying Gregorian ISO.
…ep the hydration placeholder Gregorian

Date-only Timestamp formats, PowerSearch's token value, and Schedule's labels name the month and day through Core's calendar helpers, so a Chinese or Korean month start matches Calendar, and Schedule compares calendar months with calendarMonthOf and names a month by its middle day. The clock placeholder is Gregorian, so a server without Temporal hydrates in a browser with it. The provider docs name the components that follow the calendar, and the records state that an explicit -u-ca- locale is the application's request.
@nynexman4464
nynexman4464 force-pushed the nynexman4464/feat/calendar-systems-core branch from 53da574 to fe3c951 Compare November 3, 2026 22:39
@nynexman4464
nynexman4464 force-pushed the nynexman4464/feat/calendar-formatters branch from 48a3e9e to 6c500c9 Compare November 3, 2026 22:40

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approval waits on an engineering owner's decision: built-in date formats that follow the provider's calendar (Timestamp's date formats, its hover card and accessible name, PowerSearch values, Schedule labels, the switch for existing -u-ca- locales, and the new calendar arguments on formatSharedDate and formatFilterValue), together with the rewritten Timestamp FR2/FR3 and the new browser-support exceptions in the Timestamp and PowerSearch records, rest only on the draft spec:AST-111 FR18, which is not on main, while the current internationalization architecture (INV10) and Timestamp FR2 still pin the Gregorian calendar. An engineering owner records that decision by commenting /approve-spec <full head SHA> on this pull request; the author may do so as an engineering owner.

Whatever the decision, these need fixing:

  • Timestamp's date_time and full date (formatInstant.ts:195, :230), formatDateAbsolute, formatSharedDate, Schedule's month title, week and event ranges, and the chart helpers pass the resolved calendar straight to Intl instead of through Core's calendar labels, so under calendar="iso8601" date_time reads "2026 Oct 30, 12:00 PM" in Chromium and loses its month in Node 24 while date_long and Calendar read "October 30, 2026", and Chinese and Korean dates in formatSharedDate and Schedule's ranges can name another day than Calendar; route them through one Core helper that applies labelCalendar and Temporal's day, and add iso8601 to the tests.
  • The title names charts, whose formatters never read the provider, and the body says Astryx call sites pass the calendar to formatSharedDate and that a Timestamp and a Calendar always agree, so narrow that wording.

Two new comments run past the comment style's sentence limit; suggested rewrites are inline.

[Automated review]

...zoneName,
...zone,
calendar: 'gregory',
calendar,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Under calendar="iso8601" this writes "2026 Oct 30, 12:00 PM" in Chromium 149 and "2026 30, 12:00 PM", with no month, in Node 24, while date_long above goes through formatInstantDate and Core's labelCalendar and reads "October 30, 2026". full at line 195 has the same problem, and it feeds the hover card and the relative accessible name. Route the date part through the shared calendar formatter (extended for a time of day), or at least apply labelCalendar, and add iso8601 to the calendar test matrix.

return plainDateFormat(pd, SHARED_DATE_FORMAT_OPTIONS[format], locale);
return plainDateFormat(
pd,
{...SHARED_DATE_FORMAT_OPTIONS[format], calendar},

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

formatSharedDate(day, 'date', 'en', 'iso8601') returns "2026 30" in Node 24, and under chinese this raw Intl path can name another day than Timestamp's date and Calendar, which go through formatCalendarDate. Use the same helper for non-Gregorian calendars.

year: 'numeric',
timeZone: timezoneID,
calendar: 'gregory',
calendar,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Under iso8601 this range reads "2026 25–31" in Node 24, and the month title from LocalizedMonthTitle (line 170) reads "2026 October" in Chromium while the table name reads "October 2026". Under chinese the range can disagree with the day numbers, which now go through formatCalendarDate. Apply Core's label calendar here, in LocalizedMonthTitle and in formatEventDateTimeRange.

// The pre-hydration placeholder is written in UTC, labelled, so
// the server and the hydrating client produce the same text in
// every time zone.
// The pre-hydration placeholder is Gregorian and in UTC, labelled,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking (comment style): this is one 28-word sentence. Suggested: "The placeholder before hydration is Gregorian and in UTC, with its zone. The server and the client then write the same text, with or without Temporal."

timeZone: timezoneID,
calendar: 'gregory',
}).format(new Date(plainDateToInstant(date, timezoneID, 12)));
// Core's helper names the month and day that its Calendar shows; raw Intl

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking (comment style): 26 words with two topics. Suggested: "Core's helper names the month and day that Calendar shows. Raw Intl can start a Chinese or Korean month on another day."

@nynexman4464 nynexman4464 changed the title feat(Timestamp, PowerSearch, Schedule, charts): built-in date formats follow the provider's calendar feat(Timestamp, PowerSearch, Schedule): write dates in the provider's calendar Nov 3, 2026

This branch was successfully deployed

1 active deployment
Preview — 6c500c95 Deployed Nov 3, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Meta Open Source bot.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants