From: Aarni Koskela Date: Fri, 15 Jul 2016 11:13:09 +0000 (+0300) Subject: Properly fall back to `long` metazone names when short forms are no-inherit X-Git-Tag: v2.5.0~12^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bece010dd32fbb5f4bbcd6a667800bdab662ddf6;p=thirdparty%2Fbabel.git Properly fall back to `long` metazone names when short forms are no-inherit Thanks to @stringtheory for the bug report! Fixes #428 --- diff --git a/babel/dates.py b/babel/dates.py index 523e4562..c84ca486 100644 --- a/babel/dates.py +++ b/babel/dates.py @@ -30,6 +30,16 @@ from babel.util import UTC, LOCALTZ from babel._compat import string_types, integer_types, number_types +# "If a given short metazone form is known NOT to be understood in a given +# locale and the parent locale has this value such that it would normally +# be inherited, the inheritance of this value can be explicitly disabled by +# use of the 'no inheritance marker' as the value, which is 3 simultaneous [sic] +# empty set characters ( U+2205 )." +# - http://www.unicode.org/reports/tr35/tr35-dates.html#Metazone_Names + +NO_INHERITANCE_MARKER = u'\u2205\u2205\u2205' + + LC_TIME = default_locale('LC_TIME') # Aliases for use in scopes where the modules are shadowed by local variables @@ -642,8 +652,13 @@ def get_timezone_name(dt_or_tzinfo=None, width='long', uncommon=False, if metazone: metazone_info = locale.meta_zones.get(metazone, {}) if width in metazone_info: - if zone_variant in metazone_info[width]: - return metazone_info[width][zone_variant] + name = metazone_info[width].get(zone_variant) + if width == 'short' and name == NO_INHERITANCE_MARKER: + # If the short form is marked no-inheritance, + # try to fall back to the long name instead. + name = metazone_info.get('long', {}).get(zone_variant) + if name: + return name # If we have a concrete datetime, we assume that the result can't be # independent of daylight savings time, so we return the GMT offset diff --git a/tests/test_dates.py b/tests/test_dates.py index b0d093ec..f74cd396 100644 --- a/tests/test_dates.py +++ b/tests/test_dates.py @@ -15,9 +15,12 @@ import calendar from datetime import date, datetime, time, timedelta import unittest +import pytest +import pytz from pytz import timezone from babel import dates, Locale +from babel.dates import NO_INHERITANCE_MARKER from babel.util import FixedOffsetTimezone @@ -761,3 +764,22 @@ def test_format_current_moment(monkeypatch): # Freeze time! Well, some of it anyway. monkeypatch.setattr(datetime_module, "datetime", frozen_datetime) assert dates.format_datetime(locale="en_US") == dates.format_datetime(frozen_instant, locale="en_US") + + +@pytest.mark.all_locales +def test_no_inherit_metazone_marker_never_in_output(locale): + # See: https://github.com/python-babel/babel/issues/428 + tz = pytz.timezone('America/Los_Angeles') + t = tz.localize(datetime(2016, 1, 6, 7)) + assert NO_INHERITANCE_MARKER not in dates.format_time(t, format='long', locale=locale) + assert NO_INHERITANCE_MARKER not in dates.get_timezone_name(t, width='short', locale=locale) + + +def test_no_inherit_metazone_formatting(): + # See: https://github.com/python-babel/babel/issues/428 + tz = pytz.timezone('America/Los_Angeles') + t = tz.localize(datetime(2016, 1, 6, 7)) + assert dates.format_time(t, format='long', locale='en_US') == "7:00:00 AM PST" + assert dates.format_time(t, format='long', locale='en_GB') == "07:00:00 Pacific Standard Time" + assert dates.get_timezone_name(t, width='short', locale='en_US') == "PST" + assert dates.get_timezone_name(t, width='short', locale='en_GB') == "Pacific Standard Time"