facebook / facebook/astryx

[RFC][Draft] Explore explicit alternative calendar-system support

Open
#5,498 0 comments 0 reactions 0 assignees View on GitHub
enhancement
Dominant language
TypeScript
Stars
13.1k
Forks
1.1k
Avg merge
1d 14h
Merged PRs (30d)
669

Description

## Draft status

> **DRAFT / INCOMPLETE:** This RFC records a problem space for research. It is not a proposed API or an implementation plan. Demand, supported calendar systems, conversion semantics, switching behavior, and migration requirements have not yet been established.

## Problem Statement

Astryx date APIs currently model Gregorian dates. Locale selection controls language, numbering, field order, and other presentation details, but every date remains Gregorian. That is the safe default while Calendar, DateInput, DateRangeInput, DateTimeInput, Timestamp, chart formatters, and Schedule do not share a defined contract for other calendar systems.

Some consumers may need to display, enter, navigate, or convert dates using another calendar system. Astryx has no explicit way to request that behavior today. Allowing `Intl.DateTimeFormat` to infer a calendar from a locale tag would not solve the problem: it could change only formatting while parsing, ISO serialization, date arithmetic, constraints, and calendar-grid navigation remain Gregorian.

Until this RFC is completed and accepted, Gregorian remains the only supported calendar system. A locale such as `th-TH` localizes presentation but still renders Gregorian year 2026 rather than Buddhist year 2569.

### Existing public compatibility exception

`plainDateFormat(pd, options, locale?)` is a low-level public utility whose second parameter has always been the full `Intl.DateTimeFormatOptions` type, including `calendar`. Narrowing that type would break existing TypeScript consumers, so this helper remains a deliberately limited exception:

- When `options.calendar` is omitted, it defaults to `gregory`.
- When a caller explicitly supplies `options.calendar`, the helper honors it for display formatting only.
- The input `PlainDate` still contains Gregorian fields. The exception does not add conversion, parsing, serialization, arithmetic, constraints, grid navigation, or component support for that calendar.

No other Astryx built-in date API exposes a calendar-selection option. Calendar, DateInput, DateRangeInput, DateTimeInput, Timestamp, both chart formatter packages, PowerSearch, and Schedule use Gregorian semantics for every date-bearing built-in format. Time-only formatting does not select a calendar. Consumer-supplied custom formatting callbacks remain consumer-owned escape hatches rather than Astryx calendar support.

This compatibility exception must not grow into an implicit component contract. First-class alternative-calendar behavior still requires this RFC to define the shared value and interaction semantics.

## Evidence of Demand

**Not researched yet.** Before this RFC can be evaluated, it needs:

- Concrete consumer requests for non-Gregorian date display, entry, or navigation.
- The calendar systems and locales actually needed, rather than an assumption that every system exposed by `Intl` must be supported.
- Examples from public design systems and date-picker libraries showing whether they support display-only conversion, full calendar navigation, localized input, or all three.
- Accessibility and localization feedback from people who use those calendar systems.
- Expected behavior for users whose language and preferred calendar do not conventionally match.

## Why Existing Components Don't Cover This

The current model is intentionally Gregorian end to end:

- ISO date strings and `PlainDate` fields carry Gregorian year/month/day values.
- Date parsing interprets input as Gregorian.
- Calendar grids use Gregorian month lengths, leap-year rules, and navigation.
- Date constraints and comparisons operate on those Gregorian values.
- Locale is a presentation setting, not a calendar-system setting.

A BCP 47 locale extension such as `u-ca-buddhist` can change `Intl` output, but it cannot define how Astryx should parse, store, compare, navigate, or return the selected date. Using that extension implicitly would therefore create partial support and conflicting values across components.

## Rough Approaches to Research

These are investigation starting points, not proposed APIs.

### A. Provider-level calendar setting

Add an explicit calendar-system value beside locale so an application can switch all supported date surfaces together.

Open questions include whether runtime switching preserves the represented day or preserves the visible year/month/day fields, and how nested providers should behave.

### B. Per-component calendar setting

Allow date components and formatters to opt into a calendar independently.

This may help mixed-calendar screens, but it risks inconsistent parsing, labels, constraints, and returned values unless the shared date model also carries calendar identity.

### C. Calendar adapter or strategy

Define a calendar abstraction that owns conversion, arithmetic, parsing, formatting, and serialization, then let components consume that abstraction.

This is the broadest shape and may be necessary for correctness, but its API size, bundle cost, implementation source (`Intl`, Temporal, or another library), and extension model are all unknown.

## Unresolved Questions

1. **Demand and scope:** Which calendar systems and workflows are required? Is display-only conversion enough for any meaningful use case?
2. **Value semantics:** Does an ISO string always identify a Gregorian date that is converted for display, or can a value carry its source calendar?
3. **Conversion:** Which component or utility converts between systems, and how are eras, leap months, and out-of-range dates handled?
4. **Parsing:** How does typed input declare its calendar? How are ambiguous values, localized digits, month names, and eras parsed and validated?
5. **Calendar grids:** Who owns month lengths, first/last days, year boundaries, navigation, week numbers, and date constraints for each system?
6. **Switching:** Can calendar systems change at runtime? Does switching preserve the represented day, the instant, or the visible fields?
7. **Locale interaction:** How are language, numbering system, hour cycle, time zone, and calendar selected independently? What precedence applies to locale extensions such as `u-ca-*`?
8. **Timestamps:** Should an instant and a date-only value use the same calendar API despite their different storage semantics?
9. **Serialization and callbacks:** What do `value`, `onChange`, form submission, and machine-readable `system_*` formats return?
10. **Compatibility:** How do existing Gregorian consumers remain unchanged, and what happens when an unsupported calendar is requested?
11. **Implementation:** Can platform `Intl` and Temporal capabilities provide the required conversions and arithmetic without a new dependency?
12. **Testing:** What cross-calendar fixtures, timezone boundaries, SSR cases, and browser support matrix are required?

## Accessibility Considerations

**Incomplete; user research is required.** At minimum, the design must determine:

- How assistive technology is told which calendar system, year, and era a value uses.
- Whether calendar-grid labels and navigation announcements remain unambiguous after conversion.
- How localized numerals, month names, eras, and input instructions are communicated.
- How validation errors explain a date that is valid in one calendar but not another.
- Whether switching calendars changes focus, selection, or the represented date.

The keyboard interaction model may remain a date-grid pattern, but the spoken semantics and date arithmetic cannot be assumed to carry over unchanged.

## Performance Considerations

**Not researched yet.** Investigation should measure formatter caching, conversion cost for multi-month grids and schedules, bundle impact of any dependency or calendar data, and SSR/client consistency.

## Current Non-Goals

- Inferring calendar support solely from a locale tag.
- Allowing individual formatters to drift into another calendar while inputs and navigation remain Gregorian.
- Choosing an API before demand, conversion semantics, and switching behavior are understood.

## Pre-submission Checklist

- [x] I have read the [Contributing guide](https://github.com/facebook/astryx/wiki/Contributing)
- [x] I have read the [API Conventions](https://github.com/facebook/astryx/wiki/API-Conventions)
- [x] I have checked that existing Astryx components cannot compose to solve this
- [x] This is a general-purpose date-system concern, not specific to one product

Contributor guide

Open the contributing guide

Research direction

Start with the listed date surfaces—Calendar, DateInput, DateRangeInput, DateTimeInput, Timestamp, chart formatters, PowerSearch, Schedule—and the plainDateFormat compatibility exception. Research concrete consumer demand, supported calendar systems, conversion and switching semantics, accessibility, performance, and platform capabilities such as Intl and Temporal. Done means the RFC records evidence-backed scope, shared value and interaction semantics, compatibility behavior, and testing requirements; it does not yet define an implementation.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
frontend, internationalization
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.