From 6bbdc0e8e91a547c9f89c175d365c9abeeb45fb2 Mon Sep 17 00:00:00 2001 From: Aarni Koskela Date: Wed, 8 Jan 2025 15:16:10 +0200 Subject: [PATCH] Support short and narrow formats for format_timedelta(..., add_direction=True) (#1163) Fixes #1162 --- babel/dates.py | 8 ++++++-- tests/test_dates.py | 21 +++++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/babel/dates.py b/babel/dates.py index 5a5b541ad..2e481852a 100644 --- a/babel/dates.py +++ b/babel/dates.py @@ -940,16 +940,20 @@ def format_timedelta( else: seconds = delta locale = Locale.parse(locale) + date_fields = locale._data["date_fields"] + unit_patterns = locale._data["unit_patterns"] def _iter_patterns(a_unit): if add_direction: - unit_rel_patterns = locale._data['date_fields'][a_unit] + # Try to find the length variant version first ("year-narrow") + # before falling back to the default. + unit_rel_patterns = (date_fields.get(f"{a_unit}-{format}") or date_fields[a_unit]) if seconds >= 0: yield unit_rel_patterns['future'] else: yield unit_rel_patterns['past'] a_unit = f"duration-{a_unit}" - unit_pats = locale._data['unit_patterns'].get(a_unit, {}) + unit_pats = unit_patterns.get(a_unit, {}) yield unit_pats.get(format) # We do not support `` tags at all while ingesting CLDR data, # so these aliases specified in `root.xml` are hard-coded here: diff --git a/tests/test_dates.py b/tests/test_dates.py index 8992bedcf..6c0a7ab17 100644 --- a/tests/test_dates.py +++ b/tests/test_dates.py @@ -807,3 +807,24 @@ def test_issue_892(): def test_issue_1089(): assert dates.format_datetime(datetime.now(), locale="ja_JP@mod") assert dates.format_datetime(datetime.now(), locale=Locale.parse("ja_JP@mod")) + + +@pytest.mark.parametrize(('locale', 'format', 'negative', 'expected'), [ + ('en_US', 'long', False, 'in 3 hours'), + ('en_US', 'long', True, '3 hours ago'), + ('en_US', 'narrow', False, 'in 3h'), + ('en_US', 'narrow', True, '3h ago'), + ('en_US', 'short', False, 'in 3 hr.'), + ('en_US', 'short', True, '3 hr. ago'), + ('fi_FI', 'long', False, '3 tunnin päästä'), + ('fi_FI', 'long', True, '3 tuntia sitten'), + ('fi_FI', 'short', False, '3 t päästä'), + ('fi_FI', 'short', True, '3 t sitten'), + ('sv_SE', 'long', False, 'om 3 timmar'), + ('sv_SE', 'long', True, 'för 3 timmar sedan'), + ('sv_SE', 'short', False, 'om 3 tim'), + ('sv_SE', 'short', True, 'för 3 tim sedan'), +]) +def test_issue_1162(locale, format, negative, expected): + delta = timedelta(seconds=10800) * (-1 if negative else +1) + assert dates.format_timedelta(delta, add_direction=True, format=format, locale=locale) == expected