Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

get_period_id() incorrectly handles day period rule crossing 0:00 since Babel 2.4.0 #870

Closed
jun66j5 opened this issue May 1, 2022 · 2 comments

Comments

@jun66j5
Copy link
Contributor

jun66j5 commented May 1, 2022

Overview Description

According to https://github.com/unicode-org/cldr/blob/release-41/common/supplemental/dayPeriods.xml#L15-L22, there is dayPeriodRule crossing 0:00 for en locale.

<dayPeriodRules locales="en">
        ...
        <dayPeriodRule type="night1" from="21:00" before="06:00"/>      <!-- night -->
</dayPeriodRules>

I noticed get_period_id() incorrectly handles this day period rule.

>>> dates.get_period_id(time(23), locale=en_US)
'pm'  # => should be 'night1'
>>> dates.get_period_id(time(1), locale=en_US)
'am'  # => should be 'night1'

Steps to Reproduce

>>> from datetime import time
>>> from babel import Locale, dates
>>> en_US = Locale.parse('en_US')
>>> dates.get_period_id(time(23), locale=en_US)
'pm'  # => should be 'night1'
>>> dates.get_period_id(time(1), locale=en_US)
'am'  # => should be 'night1'
>>> en_US = Locale.parse('en_US')
>>> for h in range(24):
...   t = time(h)
...   print(t, dates.get_period_id(t, locale=en_US))
...
00:00:00 midnight
01:00:00 am
02:00:00 am
03:00:00 am
04:00:00 am
05:00:00 am
06:00:00 morning1
07:00:00 morning1
08:00:00 morning1
09:00:00 morning1
10:00:00 morning1
11:00:00 morning1
12:00:00 noon
13:00:00 afternoon1
14:00:00 afternoon1
15:00:00 afternoon1
16:00:00 afternoon1
17:00:00 afternoon1
18:00:00 evening1
19:00:00 evening1
20:00:00 evening1
21:00:00 pm
22:00:00 pm
23:00:00 pm

Actual Results

>>> dates.get_period_id(time(23), locale=en_US)
'pm'
>>> dates.get_period_id(time(1), locale=en_US)
'am''

Expected Results

dates.get_period_id(time(23), locale=en_US) and dates.get_period_id(time(1), locale=en_US) should return 'night1'.

Also, we should add unit tests for get_period_id().

Reproducibility

The issue occurs with Babel 2.4.0 and later, however doesn't with 2.3.0 - 2.3.4.

Additional Information

It seems to be caused by changes of day period rule between Babel 2.3.4 (CLDR 28) and 2.4.0 (CLDR 29).

See also 8th list in https://unicode.org/reports/tr35/tr35-dates.html#4512-variable-periods

>>> import babel
>>> babel.__version__
'2.3.4'
>>> en_US = babel.Locale.parse('en_US')
>>> for _ in en_US.day_period_rules.get(None, {}).items(): _
...
('noon', [{'at': 43200}])
('morning1', [{'from': 21600, 'before': 43200}])
('afternoon1', [{'after': 43200, 'before': 64800}])
('night1', [{'after': 0, 'before': 21600}, {'from': 75600, 'before': 86400}])
('evening1', [{'from': 64800, 'before': 75600}])
('midnight', [{'at': 0}])
>>> import babel
>>> babel.__version__
'2.4.0'
>>> en_US = babel.Locale.parse('en_US')
>>> for _ in en_US.day_period_rules.get(None, {}).items(): _
...
('midnight', [{'at': 0}])
('noon', [{'at': 43200}])
('morning1', [{'before': 43200, 'from': 21600}])
('afternoon1', [{'before': 64800, 'from': 43200}])
('evening1', [{'before': 75600, 'from': 64800}])
('night1', [{'before': 21600, 'from': 75600}])
@akx
Copy link
Member

akx commented May 10, 2022

Great catch!

I suspect the breaking commit was 34c92cb.

@akx
Copy link
Member

akx commented May 10, 2022

Fixed by #871.

@akx akx closed this as completed May 10, 2022
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

No branches or pull requests

2 participants