Skip to content

dates: extract era and day-period fields for interval formatting - #1404

Open
simpleqt wants to merge 1 commit into
python-babel:masterfrom
simpleqt:fix/interval-era-day-period
Open

simpleqt wants to merge 1 commit into
python-babel:masterfrom
simpleqt:fix/interval-era-day-period

Conversation

@simpleqt

Copy link
Copy Markdown

format_interval() raised NotImplementedError for every skeleton whose CLDR interval pattern defines the era (G) or the day period (B), because DateTimeFormat.extract() only understood y M d H h m a:

>>> from babel.dates import format_interval, format_skeleton
>>> format_skeleton('Gy', datetime(2020, 1, 1), locale='en')                      # works
'2020 AD'
>>> format_interval(datetime(2020, 1, 1), datetime(2021, 1, 1), 'Gy', locale='en')
NotImplementedError: Not implemented: extracting 'G' field from pattern Gy

interval_formats defines those fields for every locale, so 13 skeletons are affected everywhere — Gy, GyM, GyMd, GyMEd, GyMMM, GyMMMd, GyMMMEd, GyMMMM, GyMMMMd, GyMMMMEd, GyMMMEEEEd, Bh and Bhm — 1,121 locales in all.

This extracts the two fields the same way they are rendered: the era index as format_era() computes it, and the day-period identifier from format_period(). The return annotation widens to int | str, matching the existing a case, and the value picked is the one for the field the two instants differ in, so the output follows the CLDR pattern selected for it:

en  Gy    2016 – 2017 AD
en  GyM   1/2016 – 3/2017 AD
en  Bh    11 in the morning – 4 in the afternoon
en  Bhm   11 in the morning – 4 in the afternoon

A sweep over all locales, all interval skeletons and a set of instants (230,698 cases) goes from 20,220 NotImplementedErrors to none, with 20,132 of those cases returning output instead of raising and no case whose output changed — nothing that used to succeed formats differently now.

tests/test_date_intervals.py::test_format_interval_era_and_day_period covers the four skeletons above: 4 failed before, 14 passed after in that file. The full suite is 1 failed / 7,831 passed with the change (the remaining failure, test_setuptools_commands, is environment-only and fails on the default branch too).

format_interval() raises NotImplementedError for any skeleton whose CLDR
interval pattern defines the era ('G') or day period ('B') field, because
DateTimeFormat.extract() only understood y M d H h m a. The affected
skeletons (Gy, GyM, GyMd, GyMEd, GyMMM, GyMMMd, GyMMMEd, GyMMMM,
GyMMMMd, GyMMMMEd, GyMMMEEEEd, Bh, Bhm) are defined in interval_formats
for every locale, so format_interval(datetime(2020, 1, 1),
datetime(2021, 1, 1), 'Gy', locale='en') failed with
"Not implemented: extracting 'G' ...".

Extract those two fields, mirroring how they are rendered: the era index
from format_era() and the day period identifier from format_period().

Sweeping all locales, interval skeletons and instants (230,698 cases)
shows 20,220 NotImplementedError crashes on the base, 0 after the fix,
with no case that previously produced output changing its output.
Copilot AI balanced review requested due to automatic review settings October 24, 2026 14:30

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota.

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants