diff --git a/tests/test_core.py b/tests/test_core.py
index 117f8697c..2c1e6d92e 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -16,34 +16,6 @@
from babel.core import Locale, default_locale
-def test_locale_provides_access_to_cldr_locale_data():
- locale = Locale('en', 'US')
- assert locale.display_name == 'English (United States)'
- assert locale.number_symbols["latn"]['decimal'] == '.'
-
-
-def test_locale_repr():
- # fmt: off
- assert repr(Locale('en', 'US')) == "Locale('en', territory='US')"
- assert repr(Locale('de', 'DE')) == "Locale('de', territory='DE')"
- assert repr(Locale('zh', 'CN', script='Hans')) == "Locale('zh', territory='CN', script='Hans')"
- # fmt: on
-
-
-def test_locale_comparison():
- en_US = Locale('en', 'US')
- en_US_2 = Locale('en', 'US')
- fi_FI = Locale('fi', 'FI')
- bad_en_US = Locale('en_US')
- assert en_US == en_US
- assert en_US == en_US_2
- assert en_US != fi_FI
- assert not (en_US != en_US_2)
- assert en_US is not None
- assert en_US != bad_en_US
- assert fi_FI != bad_en_US
-
-
def test_can_return_default_locale(monkeypatch):
monkeypatch.setenv('LC_MESSAGES', 'fr_FR.UTF-8')
assert Locale('fr', 'FR') == Locale.default('LC_MESSAGES')
@@ -71,206 +43,6 @@ def test_zone_aliases_and_territories():
assert aliases['Europe/Kiev'] == 'Europe/Kyiv'
-def test_hash():
- locale_a = Locale('en', 'US')
- locale_b = Locale('en', 'US')
- locale_c = Locale('fi', 'FI')
- assert hash(locale_a) == hash(locale_b)
- assert hash(locale_a) != hash(locale_c)
-
-
-class TestLocaleClass:
- def test_attributes(self):
- locale = Locale('en', 'US')
- assert locale.language == 'en'
- assert locale.territory == 'US'
-
- def test_default(self, monkeypatch):
- for name in ['LANGUAGE', 'LC_ALL', 'LC_CTYPE', 'LC_MESSAGES']:
- monkeypatch.setenv(name, '')
- monkeypatch.setenv('LANG', 'fr_FR.UTF-8')
- default = Locale.default('LC_MESSAGES')
- assert (default.language, default.territory) == ('fr', 'FR')
-
- def test_negotiate(self):
- de_DE = Locale.negotiate(['de_DE', 'en_US'], ['de_DE', 'de_AT'])
- assert (de_DE.language, de_DE.territory) == ('de', 'DE')
- de = Locale.negotiate(['de_DE', 'en_US'], ['en', 'de'])
- assert (de.language, de.territory) == ('de', None)
- nothing = Locale.negotiate(['de_DE', 'de'], ['en_US'])
- assert nothing is None
-
- def test_negotiate_custom_separator(self):
- de_DE = Locale.negotiate(['de-DE', 'de'], ['en-us', 'de-de'], sep='-')
- assert (de_DE.language, de_DE.territory) == ('de', 'DE')
-
- def test_parse(self):
- locale = Locale.parse('de-DE', sep='-')
- assert locale.display_name == 'Deutsch (Deutschland)'
-
- de_DE = Locale.parse(locale)
- assert (de_DE.language, de_DE.territory) == ('de', 'DE')
-
- def test_parse_likely_subtags(self):
- locale = Locale.parse('zh-TW', sep='-')
- assert locale.language == 'zh'
- assert locale.territory == 'TW'
- assert locale.script == 'Hant'
-
- locale = Locale.parse('zh_CN')
- assert locale.language == 'zh'
- assert locale.territory == 'CN'
- assert locale.script == 'Hans'
-
- locale = Locale.parse('zh_SG')
- assert locale.language == 'zh'
- assert locale.territory == 'SG'
- assert locale.script == 'Hans'
-
- locale = Locale.parse('und_AT')
- assert locale.language == 'de'
- assert locale.territory == 'AT'
-
- locale = Locale.parse('und_UK')
- assert locale.language == 'en'
- assert locale.territory == 'GB'
- assert locale.script is None
-
- def test_get_display_name(self):
- zh_CN = Locale('zh', 'CN', script='Hans')
- assert zh_CN.get_display_name('en') == 'Chinese (Simplified, China)'
-
- def test_display_name_property(self):
- assert Locale('en').display_name == 'English'
- assert Locale('en', 'US').display_name == 'English (United States)'
- assert Locale('sv').display_name == 'svenska'
-
- def test_english_name_property(self):
- assert Locale('de').english_name == 'German'
- assert Locale('de', 'DE').english_name == 'German (Germany)'
-
- def test_languages_property(self):
- assert Locale('de', 'DE').languages['ja'] == 'Japanisch'
-
- def test_scripts_property(self):
- assert Locale('en', 'US').scripts['Hira'] == 'Hiragana'
-
- def test_territories_property(self):
- assert Locale('es', 'CO').territories['DE'] == 'Alemania'
-
- def test_variants_property(self):
- assert Locale('de', 'DE').variants['1901'] == 'Alte deutsche Rechtschreibung'
-
- def test_currencies_property(self):
- assert Locale('en').currencies['COP'] == 'Colombian Peso'
- assert Locale('de', 'DE').currencies['COP'] == 'Kolumbianischer Peso'
-
- def test_currency_symbols_property(self):
- assert Locale('en', 'US').currency_symbols['USD'] == '$'
- assert Locale('es', 'CO').currency_symbols['USD'] == 'US$'
-
- def test_number_symbols_property(self):
- assert Locale('fr', 'FR').number_symbols["latn"]['decimal'] == ','
- assert Locale('ar', 'IL').number_symbols["arab"]['percentSign'] == '٪\u061c'
- assert Locale('ar', 'IL').number_symbols["latn"]['percentSign'] == '\u200e%\u200e'
-
- def test_other_numbering_systems_property(self):
- assert Locale('fr', 'FR').other_numbering_systems['native'] == 'latn'
- assert 'traditional' not in Locale('fr', 'FR').other_numbering_systems
-
- assert Locale('el', 'GR').other_numbering_systems['native'] == 'latn'
- assert Locale('el', 'GR').other_numbering_systems['traditional'] == 'grek'
-
- def test_default_numbering_systems_property(self):
- assert Locale('en', 'GB').default_numbering_system == 'latn'
- assert Locale('ar', 'EG').default_numbering_system == 'arab'
-
- @pytest.mark.all_locales
- def test_all_locales_have_default_numbering_system(self, locale):
- locale = Locale.parse(locale)
- assert locale.default_numbering_system
-
- def test_decimal_formats(self):
- assert Locale('en', 'US').decimal_formats[None].pattern == '#,##0.###'
-
- def test_currency_formats_property(self):
- en_us_currency_format = Locale('en', 'US').currency_formats
- assert en_us_currency_format['standard'].pattern == '\xa4#,##0.00'
- assert en_us_currency_format['accounting'].pattern == '\xa4#,##0.00;(\xa4#,##0.00)'
-
- def test_percent_formats_property(self):
- assert Locale('en', 'US').percent_formats[None].pattern == '#,##0%'
-
- def test_scientific_formats_property(self):
- assert Locale('en', 'US').scientific_formats[None].pattern == '#E0'
-
- def test_periods_property(self):
- assert Locale('en', 'US').periods['am'] == 'AM'
-
- def test_days_property(self):
- assert Locale('de', 'DE').days['format']['wide'][3] == 'Donnerstag'
-
- def test_months_property(self):
- assert Locale('de', 'DE').months['format']['wide'][10] == 'Oktober'
-
- def test_quarters_property(self):
- assert Locale('de', 'DE').quarters['format']['wide'][1] == '1. Quartal'
-
- def test_eras_property(self):
- assert Locale('en', 'US').eras['wide'][1] == 'Anno Domini'
- assert Locale('en', 'US').eras['abbreviated'][0] == 'BC'
-
- def test_time_zones_property(self):
- time_zones = Locale('en', 'US').time_zones
- assert time_zones['Europe/London']['long']['daylight'] == 'British Summer Time'
- assert time_zones['America/St_Johns']['city'] == 'St. John\u2019s'
-
- def test_meta_zones_property(self):
- meta_zones = Locale('en', 'US').meta_zones
- assert (
- meta_zones['Europe_Central']['long']['daylight'] == 'Central European Summer Time'
- )
-
- def test_zone_formats_property(self):
- assert Locale('en', 'US').zone_formats['fallback'] == '%(1)s (%(0)s)'
- assert Locale('pt', 'BR').zone_formats['region'] == 'Hor\xe1rio %s'
-
- def test_first_week_day_property(self):
- assert Locale('de', 'DE').first_week_day == 0
- assert Locale('en', 'US').first_week_day == 6
-
- def test_weekend_start_property(self):
- assert Locale('de', 'DE').weekend_start == 5
-
- def test_weekend_end_property(self):
- assert Locale('de', 'DE').weekend_end == 6
-
- def test_min_week_days_property(self):
- assert Locale('de', 'DE').min_week_days == 4
-
- def test_date_formats_property(self):
- assert Locale('en', 'US').date_formats['short'].pattern == 'M/d/yy'
- assert Locale('fr', 'FR').date_formats['long'].pattern == 'd MMMM y'
-
- def test_time_formats_property(self):
- assert Locale('en', 'US').time_formats['short'].pattern == 'h:mm\u202fa'
- assert Locale('fr', 'FR').time_formats['long'].pattern == 'HH:mm:ss z'
-
- def test_datetime_formats_property(self):
- assert Locale('en').datetime_formats['full'] == "{1}, {0}"
- assert Locale('th').datetime_formats['medium'] == '{1} {0}'
-
- def test_datetime_skeleton_property(self):
- assert Locale('en').datetime_skeletons['Md'].pattern == "M/d"
- assert Locale('th').datetime_skeletons['Md'].pattern == 'd/M'
-
- def test_plural_form_property(self):
- assert Locale('en').plural_form(1) == 'one'
- assert Locale('en').plural_form(0) == 'other'
- assert Locale('fr').plural_form(0) == 'one'
- assert Locale('ru').plural_form(100) == 'many'
-
-
def test_default_locale(monkeypatch):
for name in ['LANGUAGE', 'LANG', 'LC_ALL', 'LC_CTYPE', 'LC_MESSAGES']:
monkeypatch.setenv(name, '')
@@ -399,19 +171,6 @@ def test_issue_1112():
)
-def test_language_alt_official_not_used():
- # If there exists an official and customary language name, the customary
- # name should be used.
- #
- # For example, here 'Muscogee' should be used instead of 'Mvskoke':
- # Muscogee
- # Mvskoke
-
- locale = Locale('mus')
- assert locale.get_display_name() == 'Mvskoke'
- assert locale.get_display_name(Locale('en')) == 'Muscogee'
-
-
def test_locale_parse_empty():
with pytest.raises(ValueError, match="Empty") as ei:
Locale.parse("")
diff --git a/tests/test_date_time_format.py b/tests/test_date_time_format.py
new file mode 100644
index 000000000..5ca620879
--- /dev/null
+++ b/tests/test_date_time_format.py
@@ -0,0 +1,226 @@
+from datetime import date, datetime, time
+
+from babel.dates import DateTimeFormat, _localize
+
+
+def test_quarter_format():
+ d = date(2006, 6, 8)
+ fmt = DateTimeFormat(d, locale='en_US')
+ assert fmt['Q'] == '2'
+ assert fmt['QQQQ'] == '2nd quarter'
+ assert fmt['q'] == '2'
+ assert fmt['qqqq'] == '2nd quarter'
+ d = date(2006, 12, 31)
+ fmt = DateTimeFormat(d, locale='en_US')
+ assert fmt['qqq'] == 'Q4'
+ assert fmt['qqqqq'] == '4'
+ assert fmt['QQQ'] == 'Q4'
+ assert fmt['QQQQQ'] == '4'
+
+
+def test_month_context():
+ d = date(2006, 2, 8)
+ assert DateTimeFormat(d, locale='mt_MT')['MMMMM'] == 'F' # narrow format
+ assert DateTimeFormat(d, locale='mt_MT')['LLLLL'] == 'Fr' # narrow standalone
+
+
+def test_abbreviated_month_alias():
+ d = date(2006, 3, 8)
+ assert DateTimeFormat(d, locale='de_DE')['LLL'] == 'Mär'
+
+
+def test_week_of_year_first():
+ d = date(2006, 1, 8)
+ assert DateTimeFormat(d, locale='de_DE')['w'] == '1'
+ assert DateTimeFormat(d, locale='en_US')['ww'] == '02'
+
+
+def test_week_of_year_first_with_year():
+ d = date(2006, 1, 1)
+ fmt = DateTimeFormat(d, locale='de_DE')
+ assert fmt['w'] == '52'
+ assert fmt['YYYY'] == '2005'
+
+
+def test_week_of_year_last():
+ d = date(2006, 12, 26)
+ assert DateTimeFormat(d, locale='de_DE')['w'] == '52'
+ assert DateTimeFormat(d, locale='en_US')['w'] == '52'
+
+
+def test_week_of_year_last_us_extra_week():
+ d = date(2005, 12, 26)
+ assert DateTimeFormat(d, locale='de_DE')['w'] == '52'
+ assert DateTimeFormat(d, locale='en_US')['w'] == '53'
+
+
+def test_week_of_year_de_first_us_last_with_year():
+ d = date(2018, 12, 31)
+ fmt = DateTimeFormat(d, locale='de_DE')
+ assert fmt['w'] == '1'
+ assert fmt['YYYY'] == '2019'
+ fmt = DateTimeFormat(d, locale='en_US')
+ # See 363ad753, issue #1179
+ assert fmt['w'] == '1'
+ assert fmt['YYYY'] == '2019'
+
+
+def test_week_of_month_first():
+ d = date(2006, 1, 8)
+ assert DateTimeFormat(d, locale='de_DE')['W'] == '1'
+ assert DateTimeFormat(d, locale='en_US')['W'] == '2'
+
+
+def test_week_of_month_last():
+ d = date(2006, 1, 29)
+ assert DateTimeFormat(d, locale='de_DE')['W'] == '4'
+ assert DateTimeFormat(d, locale='en_US')['W'] == '5'
+
+
+def test_day_of_year():
+ d = date(2007, 4, 1)
+ assert DateTimeFormat(d, locale='en_US')['D'] == '91'
+
+
+def test_day_of_year_works_with_datetime():
+ d = datetime(2007, 4, 1)
+ assert DateTimeFormat(d, locale='en_US')['D'] == '91'
+
+
+def test_day_of_year_first():
+ d = date(2007, 1, 1)
+ assert DateTimeFormat(d, locale='en_US')['DDD'] == '001'
+
+
+def test_day_of_year_last():
+ d = date(2007, 12, 31)
+ assert DateTimeFormat(d, locale='en_US')['DDD'] == '365'
+
+
+def test_day_of_week_in_month():
+ d = date(2007, 4, 15)
+ assert DateTimeFormat(d, locale='en_US')['F'] == '3'
+
+
+def test_day_of_week_in_month_first():
+ d = date(2007, 4, 1)
+ assert DateTimeFormat(d, locale='en_US')['F'] == '1'
+
+
+def test_day_of_week_in_month_last():
+ d = date(2007, 4, 29)
+ assert DateTimeFormat(d, locale='en_US')['F'] == '5'
+
+
+def test_local_day_of_week():
+ d = date(2007, 4, 1) # a sunday
+ assert DateTimeFormat(d, locale='de_DE')['e'] == '7' # monday is first day of week
+ assert DateTimeFormat(d, locale='en_US')['ee'] == '01' # sunday is first day of week
+ assert DateTimeFormat(d, locale='ar_BH')['ee'] == '02' # saturday is first day of week
+
+ d = date(2007, 4, 2) # a monday
+ assert DateTimeFormat(d, locale='de_DE')['e'] == '1' # monday is first day of week
+ assert DateTimeFormat(d, locale='en_US')['ee'] == '02' # sunday is first day of week
+ assert DateTimeFormat(d, locale='ar_BH')['ee'] == '03' # saturday is first day of week
+
+
+def test_local_day_of_week_standalone():
+ d = date(2007, 4, 1) # a sunday
+ assert DateTimeFormat(d, locale='de_DE')['c'] == '7' # monday is first day of week
+ assert DateTimeFormat(d, locale='en_US')['c'] == '1' # sunday is first day of week
+ assert DateTimeFormat(d, locale='ar_BH')['c'] == '2' # saturday is first day of week
+
+ d = date(2007, 4, 2) # a monday
+ assert DateTimeFormat(d, locale='de_DE')['c'] == '1' # monday is first day of week
+ assert DateTimeFormat(d, locale='en_US')['c'] == '2' # sunday is first day of week
+ assert DateTimeFormat(d, locale='ar_BH')['c'] == '3' # saturday is first day of week
+
+
+def test_pattern_day_of_week():
+ dt = datetime(2016, 2, 6)
+ fmt = DateTimeFormat(dt, locale='en_US')
+ assert fmt['c'] == '7'
+ assert fmt['ccc'] == 'Sat'
+ assert fmt['cccc'] == 'Saturday'
+ assert fmt['ccccc'] == 'S'
+ assert fmt['cccccc'] == 'Sa'
+ assert fmt['e'] == '7'
+ assert fmt['ee'] == '07'
+ assert fmt['eee'] == 'Sat'
+ assert fmt['eeee'] == 'Saturday'
+ assert fmt['eeeee'] == 'S'
+ assert fmt['eeeeee'] == 'Sa'
+ assert fmt['E'] == 'Sat'
+ assert fmt['EE'] == 'Sat'
+ assert fmt['EEE'] == 'Sat'
+ assert fmt['EEEE'] == 'Saturday'
+ assert fmt['EEEEE'] == 'S'
+ assert fmt['EEEEEE'] == 'Sa'
+ fmt = DateTimeFormat(dt, locale='uk')
+ assert fmt['c'] == '6'
+ assert fmt['e'] == '6'
+ assert fmt['ee'] == '06'
+
+
+def test_fractional_seconds():
+ t = time(8, 3, 9, 799)
+ assert DateTimeFormat(t, locale='en_US')['S'] == '0'
+ t = time(8, 3, 1, 799)
+ assert DateTimeFormat(t, locale='en_US')['SSSS'] == '0008'
+ t = time(8, 3, 1, 34567)
+ assert DateTimeFormat(t, locale='en_US')['SSSS'] == '0346'
+ t = time(8, 3, 1, 345678)
+ assert DateTimeFormat(t, locale='en_US')['SSSSSS'] == '345678'
+ t = time(8, 3, 1, 799)
+ assert DateTimeFormat(t, locale='en_US')['SSSSS'] == '00080'
+
+
+def test_fractional_seconds_zero():
+ t = time(15, 30, 0)
+ assert DateTimeFormat(t, locale='en_US')['SSSS'] == '0000'
+
+
+def test_milliseconds_in_day():
+ t = time(15, 30, 12, 345000)
+ assert DateTimeFormat(t, locale='en_US')['AAAA'] == '55812345'
+
+
+def test_milliseconds_in_day_zero():
+ d = time(0, 0, 0)
+ assert DateTimeFormat(d, locale='en_US')['AAAA'] == '0000'
+
+
+def test_timezone_rfc822(timezone_getter):
+ tz = timezone_getter('Europe/Berlin')
+ t = _localize(tz, datetime(2015, 1, 1, 15, 30))
+ assert DateTimeFormat(t, locale='de_DE')['Z'] == '+0100'
+
+
+def test_timezone_gmt(timezone_getter):
+ tz = timezone_getter('Europe/Berlin')
+ t = _localize(tz, datetime(2015, 1, 1, 15, 30))
+ assert DateTimeFormat(t, locale='de_DE')['ZZZZ'] == 'GMT+01:00'
+
+
+def test_timezone_name(timezone_getter):
+ tz = timezone_getter('Europe/Paris')
+ dt = _localize(tz, datetime(2007, 4, 1, 15, 30))
+ assert DateTimeFormat(dt, locale='fr_FR')['v'] == 'heure : France'
+
+
+def test_timezone_location_format(timezone_getter):
+ tz = timezone_getter('Europe/Paris')
+ dt = _localize(tz, datetime(2007, 4, 1, 15, 30))
+ assert DateTimeFormat(dt, locale='fr_FR')['VVVV'] == 'heure : France'
+
+
+def test_timezone_walltime_short(timezone_getter):
+ tz = timezone_getter('Europe/Paris')
+ t = time(15, 30, tzinfo=tz)
+ assert DateTimeFormat(t, locale='fr_FR')['v'] == 'heure : France'
+
+
+def test_timezone_walltime_long(timezone_getter):
+ tz = timezone_getter('Europe/Paris')
+ t = time(15, 30, tzinfo=tz)
+ assert DateTimeFormat(t, locale='fr_FR')['vvvv'] == 'heure d’Europe centrale'
diff --git a/tests/test_dates.py b/tests/test_dates.py
index 2eacdb312..4f8c73907 100644
--- a/tests/test_dates.py
+++ b/tests/test_dates.py
@@ -21,380 +21,182 @@
from babel.util import FixedOffsetTimezone
-class DateTimeFormatTestCase:
-
- def test_quarter_format(self):
- d = date(2006, 6, 8)
- fmt = dates.DateTimeFormat(d, locale='en_US')
- assert fmt['Q'] == '2'
- assert fmt['QQQQ'] == '2nd quarter'
- assert fmt['q'] == '2'
- assert fmt['qqqq'] == '2nd quarter'
- d = date(2006, 12, 31)
- fmt = dates.DateTimeFormat(d, locale='en_US')
- assert fmt['qqq'] == 'Q4'
- assert fmt['qqqqq'] == '4'
- assert fmt['QQQ'] == 'Q4'
- assert fmt['QQQQQ'] == '4'
-
- def test_month_context(self):
- d = date(2006, 2, 8)
- assert dates.DateTimeFormat(d, locale='mt_MT')['MMMMM'] == 'F' # narrow format
- assert dates.DateTimeFormat(d, locale='mt_MT')['LLLLL'] == 'Fr' # narrow standalone
-
- def test_abbreviated_month_alias(self):
- d = date(2006, 3, 8)
- assert dates.DateTimeFormat(d, locale='de_DE')['LLL'] == 'Mär'
-
- def test_week_of_year_first(self):
- d = date(2006, 1, 8)
- assert dates.DateTimeFormat(d, locale='de_DE')['w'] == '1'
- assert dates.DateTimeFormat(d, locale='en_US')['ww'] == '02'
-
- def test_week_of_year_first_with_year(self):
- d = date(2006, 1, 1)
- fmt = dates.DateTimeFormat(d, locale='de_DE')
- assert fmt['w'] == '52'
- assert fmt['YYYY'] == '2005'
-
- def test_week_of_year_last(self):
- d = date(2006, 12, 26)
- assert dates.DateTimeFormat(d, locale='de_DE')['w'] == '52'
- assert dates.DateTimeFormat(d, locale='en_US')['w'] == '52'
-
- def test_week_of_year_last_us_extra_week(self):
- d = date(2005, 12, 26)
- assert dates.DateTimeFormat(d, locale='de_DE')['w'] == '52'
- assert dates.DateTimeFormat(d, locale='en_US')['w'] == '53'
-
- def test_week_of_year_de_first_us_last_with_year(self):
- d = date(2018, 12, 31)
- fmt = dates.DateTimeFormat(d, locale='de_DE')
- assert fmt['w'] == '1'
- assert fmt['YYYY'] == '2019'
- fmt = dates.DateTimeFormat(d, locale='en_US')
- assert fmt['w'] == '53'
- assert fmt['yyyy'] == '2018'
-
- def test_week_of_month_first(self):
- d = date(2006, 1, 8)
- assert dates.DateTimeFormat(d, locale='de_DE')['W'] == '1'
- assert dates.DateTimeFormat(d, locale='en_US')['W'] == '2'
-
- def test_week_of_month_last(self):
- d = date(2006, 1, 29)
- assert dates.DateTimeFormat(d, locale='de_DE')['W'] == '4'
- assert dates.DateTimeFormat(d, locale='en_US')['W'] == '5'
-
- def test_day_of_year(self):
- d = date(2007, 4, 1)
- assert dates.DateTimeFormat(d, locale='en_US')['D'] == '91'
-
- def test_day_of_year_works_with_datetime(self):
- d = datetime(2007, 4, 1)
- assert dates.DateTimeFormat(d, locale='en_US')['D'] == '91'
-
- def test_day_of_year_first(self):
- d = date(2007, 1, 1)
- assert dates.DateTimeFormat(d, locale='en_US')['DDD'] == '001'
-
- def test_day_of_year_last(self):
- d = date(2007, 12, 31)
- assert dates.DateTimeFormat(d, locale='en_US')['DDD'] == '365'
-
- def test_day_of_week_in_month(self):
- d = date(2007, 4, 15)
- assert dates.DateTimeFormat(d, locale='en_US')['F'] == '3'
-
- def test_day_of_week_in_month_first(self):
- d = date(2007, 4, 1)
- assert dates.DateTimeFormat(d, locale='en_US')['F'] == '1'
-
- def test_day_of_week_in_month_last(self):
- d = date(2007, 4, 29)
- assert dates.DateTimeFormat(d, locale='en_US')['F'] == '5'
-
- def test_local_day_of_week(self):
- d = date(2007, 4, 1) # a sunday
- assert dates.DateTimeFormat(d, locale='de_DE')['e'] == '7' # monday is first day of week
- assert dates.DateTimeFormat(d, locale='en_US')['ee'] == '01' # sunday is first day of week
- assert dates.DateTimeFormat(d, locale='ar_BH')['ee'] == '02' # saturday is first day of week
-
- d = date(2007, 4, 2) # a monday
- assert dates.DateTimeFormat(d, locale='de_DE')['e'] == '1' # monday is first day of week
- assert dates.DateTimeFormat(d, locale='en_US')['ee'] == '02' # sunday is first day of week
- assert dates.DateTimeFormat(d, locale='ar_BH')['ee'] == '03' # saturday is first day of week
-
- def test_local_day_of_week_standalone(self):
- d = date(2007, 4, 1) # a sunday
- assert dates.DateTimeFormat(d, locale='de_DE')['c'] == '7' # monday is first day of week
- assert dates.DateTimeFormat(d, locale='en_US')['c'] == '1' # sunday is first day of week
- assert dates.DateTimeFormat(d, locale='ar_BH')['c'] == '2' # saturday is first day of week
-
- d = date(2007, 4, 2) # a monday
- assert dates.DateTimeFormat(d, locale='de_DE')['c'] == '1' # monday is first day of week
- assert dates.DateTimeFormat(d, locale='en_US')['c'] == '2' # sunday is first day of week
- assert dates.DateTimeFormat(d, locale='ar_BH')['c'] == '3' # saturday is first day of week
-
- def test_pattern_day_of_week(self):
- dt = datetime(2016, 2, 6)
- fmt = dates.DateTimeFormat(dt, locale='en_US')
- assert fmt['c'] == '7'
- assert fmt['ccc'] == 'Sat'
- assert fmt['cccc'] == 'Saturday'
- assert fmt['ccccc'] == 'S'
- assert fmt['cccccc'] == 'Sa'
- assert fmt['e'] == '7'
- assert fmt['ee'] == '07'
- assert fmt['eee'] == 'Sat'
- assert fmt['eeee'] == 'Saturday'
- assert fmt['eeeee'] == 'S'
- assert fmt['eeeeee'] == 'Sa'
- assert fmt['E'] == 'Sat'
- assert fmt['EE'] == 'Sat'
- assert fmt['EEE'] == 'Sat'
- assert fmt['EEEE'] == 'Saturday'
- assert fmt['EEEEE'] == 'S'
- assert fmt['EEEEEE'] == 'Sa'
- fmt = dates.DateTimeFormat(dt, locale='uk')
- assert fmt['c'] == '6'
- assert fmt['e'] == '6'
- assert fmt['ee'] == '06'
-
- def test_fractional_seconds(self):
- t = time(8, 3, 9, 799)
- assert dates.DateTimeFormat(t, locale='en_US')['S'] == '0'
- t = time(8, 3, 1, 799)
- assert dates.DateTimeFormat(t, locale='en_US')['SSSS'] == '0008'
- t = time(8, 3, 1, 34567)
- assert dates.DateTimeFormat(t, locale='en_US')['SSSS'] == '0346'
- t = time(8, 3, 1, 345678)
- assert dates.DateTimeFormat(t, locale='en_US')['SSSSSS'] == '345678'
- t = time(8, 3, 1, 799)
- assert dates.DateTimeFormat(t, locale='en_US')['SSSSS'] == '00080'
-
- def test_fractional_seconds_zero(self):
- t = time(15, 30, 0)
- assert dates.DateTimeFormat(t, locale='en_US')['SSSS'] == '0000'
-
- def test_milliseconds_in_day(self):
- t = time(15, 30, 12, 345000)
- assert dates.DateTimeFormat(t, locale='en_US')['AAAA'] == '55812345'
-
- def test_milliseconds_in_day_zero(self):
- d = time(0, 0, 0)
- assert dates.DateTimeFormat(d, locale='en_US')['AAAA'] == '0000'
-
- def test_timezone_rfc822(self, timezone_getter):
- tz = timezone_getter('Europe/Berlin')
- t = _localize(tz, datetime(2015, 1, 1, 15, 30))
- assert dates.DateTimeFormat(t, locale='de_DE')['Z'] == '+0100'
-
- def test_timezone_gmt(self, timezone_getter):
- tz = timezone_getter('Europe/Berlin')
- t = _localize(tz, datetime(2015, 1, 1, 15, 30))
- assert dates.DateTimeFormat(t, locale='de_DE')['ZZZZ'] == 'GMT+01:00'
-
- def test_timezone_name(self, timezone_getter):
- tz = timezone_getter('Europe/Paris')
- dt = _localize(tz, datetime(2007, 4, 1, 15, 30))
- assert dates.DateTimeFormat(dt, locale='fr_FR')['v'] == 'heure : France'
-
- def test_timezone_location_format(self, timezone_getter):
- tz = timezone_getter('Europe/Paris')
- dt = _localize(tz, datetime(2007, 4, 1, 15, 30))
- assert dates.DateTimeFormat(dt, locale='fr_FR')['VVVV'] == 'heure : France'
-
- def test_timezone_walltime_short(self, timezone_getter):
- tz = timezone_getter('Europe/Paris')
- t = time(15, 30, tzinfo=tz)
- assert dates.DateTimeFormat(t, locale='fr_FR')['v'] == 'heure : France'
-
- def test_timezone_walltime_long(self, timezone_getter):
- tz = timezone_getter('Europe/Paris')
- t = time(15, 30, tzinfo=tz)
- assert dates.DateTimeFormat(t, locale='fr_FR')['vvvv'] == 'heure d’Europe centrale'
-
- def test_hour_formatting(self):
- locale = 'en_US'
- t = time(0, 0, 0)
- assert dates.format_time(t, 'h a', locale=locale) == '12 AM'
- assert dates.format_time(t, 'H', locale=locale) == '0'
- assert dates.format_time(t, 'k', locale=locale) == '24'
- assert dates.format_time(t, 'K a', locale=locale) == '0 AM'
- t = time(12, 0, 0)
- assert dates.format_time(t, 'h a', locale=locale) == '12 PM'
- assert dates.format_time(t, 'H', locale=locale) == '12'
- assert dates.format_time(t, 'k', locale=locale) == '12'
- assert dates.format_time(t, 'K a', locale=locale) == '0 PM'
-
-
-class FormatDateTestCase:
-
- def test_with_time_fields_in_pattern(self):
- with pytest.raises(AttributeError):
- dates.format_date(date(2007, 4, 1), "yyyy-MM-dd HH:mm", locale='en_US')
-
- def test_with_time_fields_in_pattern_and_datetime_param(self):
- with pytest.raises(AttributeError):
- dates.format_date(datetime(2007, 4, 1, 15, 30), "yyyy-MM-dd HH:mm", locale='en_US')
-
- def test_with_day_of_year_in_pattern_and_datetime_param(self):
- # format_date should work on datetimes just as well (see #282)
- d = datetime(2007, 4, 1)
- assert dates.format_date(d, 'w', locale='en_US') == '14'
-
-
-class FormatDatetimeTestCase:
-
- def test_with_float(self, timezone_getter):
- UTC = timezone_getter('UTC')
- d = datetime(2012, 4, 1, 15, 30, 29, tzinfo=UTC)
- epoch = float(calendar.timegm(d.timetuple()))
- formatted_string = dates.format_datetime(epoch, format='long', locale='en_US')
- assert formatted_string == 'April 1, 2012 at 3:30:29 PM UTC'
-
- def test_timezone_formats_los_angeles(self, timezone_getter):
- tz = timezone_getter('America/Los_Angeles')
- dt = _localize(tz, datetime(2016, 1, 13, 7, 8, 35))
- assert dates.format_datetime(dt, 'z', locale='en') == 'PST'
- assert dates.format_datetime(dt, 'zz', locale='en') == 'PST'
- assert dates.format_datetime(dt, 'zzz', locale='en') == 'PST'
- assert dates.format_datetime(dt, 'zzzz', locale='en') == 'Pacific Standard Time'
- assert dates.format_datetime(dt, 'Z', locale='en') == '-0800'
- assert dates.format_datetime(dt, 'ZZ', locale='en') == '-0800'
- assert dates.format_datetime(dt, 'ZZZ', locale='en') == '-0800'
- assert dates.format_datetime(dt, 'ZZZZ', locale='en') == 'GMT-08:00'
- assert dates.format_datetime(dt, 'ZZZZZ', locale='en') == '-08:00'
- assert dates.format_datetime(dt, 'OOOO', locale='en') == 'GMT-08:00'
- assert dates.format_datetime(dt, 'VV', locale='en') == 'America/Los_Angeles'
- assert dates.format_datetime(dt, 'VVV', locale='en') == 'Los Angeles'
- assert dates.format_datetime(dt, 'X', locale='en') == '-08'
- assert dates.format_datetime(dt, 'XX', locale='en') == '-0800'
- assert dates.format_datetime(dt, 'XXX', locale='en') == '-08:00'
- assert dates.format_datetime(dt, 'XXXX', locale='en') == '-0800'
- assert dates.format_datetime(dt, 'XXXXX', locale='en') == '-08:00'
- assert dates.format_datetime(dt, 'x', locale='en') == '-08'
- assert dates.format_datetime(dt, 'xx', locale='en') == '-0800'
- assert dates.format_datetime(dt, 'xxx', locale='en') == '-08:00'
- assert dates.format_datetime(dt, 'xxxx', locale='en') == '-0800'
- assert dates.format_datetime(dt, 'xxxxx', locale='en') == '-08:00'
-
- def test_timezone_formats_utc(self, timezone_getter):
- tz = timezone_getter('UTC')
- dt = _localize(tz, datetime(2016, 1, 13, 7, 8, 35))
- assert dates.format_datetime(dt, 'Z', locale='en') == '+0000'
- assert dates.format_datetime(dt, 'ZZ', locale='en') == '+0000'
- assert dates.format_datetime(dt, 'ZZZ', locale='en') == '+0000'
- assert dates.format_datetime(dt, 'ZZZZ', locale='en') == 'GMT+00:00'
- assert dates.format_datetime(dt, 'ZZZZZ', locale='en') == 'Z'
- assert dates.format_datetime(dt, 'OOOO', locale='en') == 'GMT+00:00'
- assert dates.format_datetime(dt, 'VV', locale='en') == 'Etc/UTC'
- assert dates.format_datetime(dt, 'VVV', locale='en') == 'UTC'
- assert dates.format_datetime(dt, 'X', locale='en') == 'Z'
- assert dates.format_datetime(dt, 'XX', locale='en') == 'Z'
- assert dates.format_datetime(dt, 'XXX', locale='en') == 'Z'
- assert dates.format_datetime(dt, 'XXXX', locale='en') == 'Z'
- assert dates.format_datetime(dt, 'XXXXX', locale='en') == 'Z'
- assert dates.format_datetime(dt, 'x', locale='en') == '+00'
- assert dates.format_datetime(dt, 'xx', locale='en') == '+0000'
- assert dates.format_datetime(dt, 'xxx', locale='en') == '+00:00'
- assert dates.format_datetime(dt, 'xxxx', locale='en') == '+0000'
- assert dates.format_datetime(dt, 'xxxxx', locale='en') == '+00:00'
-
- def test_timezone_formats_kolkata(self, timezone_getter):
- tz = timezone_getter('Asia/Kolkata')
- dt = _localize(tz, datetime(2016, 1, 13, 7, 8, 35))
- assert dates.format_datetime(dt, 'zzzz', locale='en') == 'India Standard Time'
- assert dates.format_datetime(dt, 'ZZZZ', locale='en') == 'GMT+05:30'
- assert dates.format_datetime(dt, 'ZZZZZ', locale='en') == '+05:30'
- assert dates.format_datetime(dt, 'OOOO', locale='en') == 'GMT+05:30'
- assert dates.format_datetime(dt, 'VV', locale='en') == 'Asia/Calcutta'
- assert dates.format_datetime(dt, 'VVV', locale='en') == 'Kolkata'
- assert dates.format_datetime(dt, 'X', locale='en') == '+0530'
- assert dates.format_datetime(dt, 'XX', locale='en') == '+0530'
- assert dates.format_datetime(dt, 'XXX', locale='en') == '+05:30'
- assert dates.format_datetime(dt, 'XXXX', locale='en') == '+0530'
- assert dates.format_datetime(dt, 'XXXXX', locale='en') == '+05:30'
- assert dates.format_datetime(dt, 'x', locale='en') == '+0530'
- assert dates.format_datetime(dt, 'xx', locale='en') == '+0530'
- assert dates.format_datetime(dt, 'xxx', locale='en') == '+05:30'
- assert dates.format_datetime(dt, 'xxxx', locale='en') == '+0530'
- assert dates.format_datetime(dt, 'xxxxx', locale='en') == '+05:30'
-
-
-class FormatTimeTestCase:
-
- def test_with_naive_datetime_and_tzinfo(self, timezone_getter):
- assert dates.format_time(
- datetime(2007, 4, 1, 15, 30),
- 'long',
- tzinfo=timezone_getter('US/Eastern'),
- locale='en',
- ) == '11:30:00 AM EDT'
-
- def test_with_float(self, timezone_getter):
- tz = timezone_getter('UTC')
- d = _localize(tz, datetime(2012, 4, 1, 15, 30, 29))
- epoch = float(calendar.timegm(d.timetuple()))
- assert dates.format_time(epoch, format='long', locale='en_US') == '3:30:29 PM UTC'
-
- def test_with_date_fields_in_pattern(self):
- with pytest.raises(AttributeError):
- dates.format_time(datetime(2007, 4, 1), 'yyyy-MM-dd HH:mm', locale='en')
-
- def test_with_date_fields_in_pattern_and_datetime_param(self):
- with pytest.raises(AttributeError):
- dates.format_time(datetime(2007, 4, 1, 15, 30), "yyyy-MM-dd HH:mm", locale='en_US')
-
-
-class FormatTimedeltaTestCase:
-
- def test_zero_seconds(self):
- td = timedelta(seconds=0)
- assert dates.format_timedelta(td, locale='en') == '0 seconds'
- assert dates.format_timedelta(td, locale='en', format='short') == '0 sec'
- assert dates.format_timedelta(td, granularity='hour', locale='en') == '0 hours'
- assert dates.format_timedelta(td, granularity='hour', locale='en', format='short') == '0 hr'
-
- def test_small_value_with_granularity(self):
- td = timedelta(seconds=42)
- assert dates.format_timedelta(td, granularity='hour', locale='en') == '1 hour'
- assert dates.format_timedelta(td, granularity='hour', locale='en', format='short') == '1 hr'
-
- def test_direction_adding(self):
- td = timedelta(hours=1)
- assert dates.format_timedelta(td, locale='en', add_direction=True) == 'in 1 hour'
- assert dates.format_timedelta(-td, locale='en', add_direction=True) == '1 hour ago'
-
- def test_format_narrow(self):
- assert dates.format_timedelta(timedelta(hours=1), locale='en', format='narrow') == '1h'
- assert dates.format_timedelta(timedelta(hours=-2), locale='en', format='narrow') == '2h'
-
- def test_format_invalid(self):
- for format in (None, '', 'bold italic'):
- with pytest.raises(TypeError):
- dates.format_timedelta(timedelta(hours=1), format=format)
-
-
-class TimeZoneAdjustTestCase:
-
- def _utc(self):
- class EvilFixedOffsetTimezone(FixedOffsetTimezone):
-
- def localize(self, dt, is_dst=False):
- raise NotImplementedError()
- UTC = EvilFixedOffsetTimezone(0, 'UTC')
- # This is important to trigger the actual bug (#257)
- assert hasattr(UTC, 'normalize') is False
- return UTC
-
- def test_can_format_time_with_custom_timezone(self):
- # regression test for #257
- utc = self._utc()
- t = datetime(2007, 4, 1, 15, 30, tzinfo=utc)
- formatted_time = dates.format_time(t, 'long', tzinfo=utc, locale='en')
- assert formatted_time == '3:30:00 PM UTC'
+def test_format_date_with_time_fields_in_pattern():
+ with pytest.raises(AttributeError):
+ dates.format_date(date(2007, 4, 1), "yyyy-MM-dd HH:mm", locale='en_US')
+
+
+def test_format_date_with_time_fields_in_pattern_and_datetime_param():
+ d = datetime(2007, 4, 1, 15, 30)
+ with pytest.raises(AttributeError):
+ dates.format_date(d, "yyyy-MM-dd HH:mm", locale='en_US')
+
+
+def test_format_date_with_day_of_year_in_pattern_and_datetime_param():
+ # format_date should work on datetimes just as well (see #282)
+ d = datetime(2007, 4, 1)
+ assert dates.format_date(d, 'w', locale='en_US') == '14'
+
+
+def test_format_datetime_with_float(timezone_getter):
+ UTC = timezone_getter('UTC')
+ d = datetime(2012, 4, 1, 15, 30, 29, tzinfo=UTC)
+ epoch = float(calendar.timegm(d.timetuple()))
+ formatted_string = dates.format_datetime(epoch, format='long', locale='en_US')
+ assert formatted_string == 'April 1, 2012, 3:30:29\u202fPM UTC'
+
+
+def test_format_datetime_timezone_formats_los_angeles(timezone_getter):
+ tz = timezone_getter('America/Los_Angeles')
+ dt = _localize(tz, datetime(2016, 1, 13, 7, 8, 35))
+ assert dates.format_datetime(dt, 'z', locale='en') == 'PST'
+ assert dates.format_datetime(dt, 'zz', locale='en') == 'PST'
+ assert dates.format_datetime(dt, 'zzz', locale='en') == 'PST'
+ assert dates.format_datetime(dt, 'zzzz', locale='en') == 'Pacific Standard Time'
+ assert dates.format_datetime(dt, 'Z', locale='en') == '-0800'
+ assert dates.format_datetime(dt, 'ZZ', locale='en') == '-0800'
+ assert dates.format_datetime(dt, 'ZZZ', locale='en') == '-0800'
+ assert dates.format_datetime(dt, 'ZZZZ', locale='en') == 'GMT-08:00'
+ assert dates.format_datetime(dt, 'ZZZZZ', locale='en') == '-08:00'
+ assert dates.format_datetime(dt, 'OOOO', locale='en') == 'GMT-08:00'
+ assert dates.format_datetime(dt, 'VV', locale='en') == 'America/Los_Angeles'
+ assert dates.format_datetime(dt, 'VVV', locale='en') == 'Los Angeles'
+ assert dates.format_datetime(dt, 'X', locale='en') == '-08'
+ assert dates.format_datetime(dt, 'XX', locale='en') == '-0800'
+ assert dates.format_datetime(dt, 'XXX', locale='en') == '-08:00'
+ assert dates.format_datetime(dt, 'XXXX', locale='en') == '-0800'
+ assert dates.format_datetime(dt, 'XXXXX', locale='en') == '-08:00'
+ assert dates.format_datetime(dt, 'x', locale='en') == '-08'
+ assert dates.format_datetime(dt, 'xx', locale='en') == '-0800'
+ assert dates.format_datetime(dt, 'xxx', locale='en') == '-08:00'
+ assert dates.format_datetime(dt, 'xxxx', locale='en') == '-0800'
+ assert dates.format_datetime(dt, 'xxxxx', locale='en') == '-08:00'
+
+
+def test_format_datetime_timezone_formats_utc(timezone_getter):
+ tz = timezone_getter('UTC')
+ dt = _localize(tz, datetime(2016, 1, 13, 7, 8, 35))
+ assert dates.format_datetime(dt, 'Z', locale='en') == '+0000'
+ assert dates.format_datetime(dt, 'ZZ', locale='en') == '+0000'
+ assert dates.format_datetime(dt, 'ZZZ', locale='en') == '+0000'
+ assert dates.format_datetime(dt, 'ZZZZ', locale='en') == 'GMT+00:00'
+ assert dates.format_datetime(dt, 'ZZZZZ', locale='en') == 'Z'
+ assert dates.format_datetime(dt, 'OOOO', locale='en') == 'GMT+00:00'
+ assert dates.format_datetime(dt, 'VV', locale='en') == 'Etc/UTC'
+ assert dates.format_datetime(dt, 'VVV', locale='en') == 'UTC'
+ assert dates.format_datetime(dt, 'X', locale='en') == 'Z'
+ assert dates.format_datetime(dt, 'XX', locale='en') == 'Z'
+ assert dates.format_datetime(dt, 'XXX', locale='en') == 'Z'
+ assert dates.format_datetime(dt, 'XXXX', locale='en') == 'Z'
+ assert dates.format_datetime(dt, 'XXXXX', locale='en') == 'Z'
+ assert dates.format_datetime(dt, 'x', locale='en') == '+00'
+ assert dates.format_datetime(dt, 'xx', locale='en') == '+0000'
+ assert dates.format_datetime(dt, 'xxx', locale='en') == '+00:00'
+ assert dates.format_datetime(dt, 'xxxx', locale='en') == '+0000'
+ assert dates.format_datetime(dt, 'xxxxx', locale='en') == '+00:00'
+
+
+def test_format_datetime_timezone_formats_kolkata(timezone_getter):
+ tz = timezone_getter('Asia/Kolkata')
+ dt = _localize(tz, datetime(2016, 1, 13, 7, 8, 35))
+ assert dates.format_datetime(dt, 'zzzz', locale='en') == 'GMT+05:30'
+ assert dates.format_datetime(dt, 'ZZZZ', locale='en') == 'GMT+05:30'
+ assert dates.format_datetime(dt, 'ZZZZZ', locale='en') == '+05:30'
+ assert dates.format_datetime(dt, 'OOOO', locale='en') == 'GMT+05:30'
+ assert dates.format_datetime(dt, 'VV', locale='en') == 'Asia/Kolkata'
+ assert dates.format_datetime(dt, 'VVV', locale='en') == 'Kolkata'
+ assert dates.format_datetime(dt, 'X', locale='en') == '+0530'
+ assert dates.format_datetime(dt, 'XX', locale='en') == '+0530'
+ assert dates.format_datetime(dt, 'XXX', locale='en') == '+05:30'
+ assert dates.format_datetime(dt, 'XXXX', locale='en') == '+0530'
+ assert dates.format_datetime(dt, 'XXXXX', locale='en') == '+05:30'
+ assert dates.format_datetime(dt, 'x', locale='en') == '+0530'
+ assert dates.format_datetime(dt, 'xx', locale='en') == '+0530'
+ assert dates.format_datetime(dt, 'xxx', locale='en') == '+05:30'
+ assert dates.format_datetime(dt, 'xxxx', locale='en') == '+0530'
+ assert dates.format_datetime(dt, 'xxxxx', locale='en') == '+05:30'
+
+
+def test_format_time_with_naive_datetime_and_tzinfo(timezone_getter):
+ d = datetime(2007, 4, 1, 15, 30)
+ formatted = dates.format_time(d, 'long', tzinfo=timezone_getter('US/Eastern'), locale='en')
+ assert formatted == '11:30:00\u202fAM EDT'
+
+
+def test_format_time_with_float(timezone_getter):
+ tz = timezone_getter('UTC')
+ d = _localize(tz, datetime(2012, 4, 1, 15, 30, 29))
+ epoch = float(calendar.timegm(d.timetuple()))
+ assert dates.format_time(epoch, format='long', locale='en_US') == '3:30:29\u202fPM UTC'
+
+
+def test_format_time_with_date_fields_in_pattern():
+ with pytest.raises(AttributeError):
+ dates.format_time(datetime(2007, 4, 1), 'yyyy-MM-dd HH:mm', locale='en')
+
+
+def test_format_time_with_date_fields_in_pattern_and_datetime_param():
+ with pytest.raises(AttributeError):
+ dates.format_time(datetime(2007, 4, 1, 15, 30), "yyyy-MM-dd HH:mm", locale='en_US')
+
+
+def test_format_time_hour_formatting():
+ locale = 'en_US'
+ t = time(0, 0, 0)
+ assert dates.format_time(t, 'h a', locale=locale) == '12 AM'
+ assert dates.format_time(t, 'H', locale=locale) == '0'
+ assert dates.format_time(t, 'k', locale=locale) == '24'
+ assert dates.format_time(t, 'K a', locale=locale) == '0 AM'
+ t = time(12, 0, 0)
+ assert dates.format_time(t, 'h a', locale=locale) == '12 PM'
+ assert dates.format_time(t, 'H', locale=locale) == '12'
+ assert dates.format_time(t, 'k', locale=locale) == '12'
+ assert dates.format_time(t, 'K a', locale=locale) == '0 PM'
+
+
+def test_format_timedelta_zero_seconds():
+ td = timedelta(seconds=0)
+ assert dates.format_timedelta(td, locale='en') == '0 seconds'
+ assert dates.format_timedelta(td, locale='en', format='short') == '0 sec'
+ assert dates.format_timedelta(td, granularity='hour', locale='en') == '0 hours'
+ assert dates.format_timedelta(td, granularity='hour', locale='en', format='short') == '0 hr' # fmt: skip
+
+
+def test_format_timedelta_small_value_with_granularity():
+ td = timedelta(seconds=42)
+ assert dates.format_timedelta(td, granularity='hour', locale='en') == '1 hour'
+ assert dates.format_timedelta(td, granularity='hour', locale='en', format='short') == '1 hr' # fmt: skip
+
+
+def test_format_timedelta_direction_adding():
+ td = timedelta(hours=1)
+ assert dates.format_timedelta(td, locale='en', add_direction=True) == 'in 1 hour'
+ assert dates.format_timedelta(-td, locale='en', add_direction=True) == '1 hour ago'
+
+
+def test_format_timedelta_format_narrow():
+ assert dates.format_timedelta(timedelta(hours=1), locale='en', format='narrow') == '1h'
+ assert dates.format_timedelta(timedelta(hours=-2), locale='en', format='narrow') == '2h'
+
+
+def test_format_timedelta_format_invalid():
+ for format in (None, '', 'bold italic'):
+ with pytest.raises(TypeError):
+ dates.format_timedelta(timedelta(hours=1), format=format)
+
+
+def test_timezone_adjust_can_format_time_with_custom_timezone():
+ # regression test for #257
+ class EvilFixedOffsetTimezone(FixedOffsetTimezone):
+ def localize(self, dt, is_dst=False):
+ raise NotImplementedError()
+
+ utc = EvilFixedOffsetTimezone(0, 'UTC')
+ # This is important to trigger the actual bug (#257)
+ assert hasattr(utc, 'normalize') is False
+ t = datetime(2007, 4, 1, 15, 30, tzinfo=utc)
+ formatted_time = dates.format_time(t, 'long', tzinfo=utc, locale='en')
+ assert formatted_time == '3:30:00\u202fPM UTC'
def test_get_period_names():
diff --git a/tests/test_locale_class.py b/tests/test_locale_class.py
new file mode 100644
index 000000000..5ddb3e876
--- /dev/null
+++ b/tests/test_locale_class.py
@@ -0,0 +1,280 @@
+import pytest
+
+from babel import Locale
+
+
+def test_attributes():
+ locale = Locale('en', 'US')
+ assert locale.language == 'en'
+ assert locale.territory == 'US'
+
+
+def test_default(monkeypatch):
+ for name in ['LANGUAGE', 'LC_ALL', 'LC_CTYPE', 'LC_MESSAGES']:
+ monkeypatch.setenv(name, '')
+ monkeypatch.setenv('LANG', 'fr_FR.UTF-8')
+ default = Locale.default('LC_MESSAGES')
+ assert (default.language, default.territory) == ('fr', 'FR')
+
+
+def test_negotiate():
+ de_DE = Locale.negotiate(['de_DE', 'en_US'], ['de_DE', 'de_AT'])
+ assert (de_DE.language, de_DE.territory) == ('de', 'DE')
+ de = Locale.negotiate(['de_DE', 'en_US'], ['en', 'de'])
+ assert (de.language, de.territory) == ('de', None)
+ nothing = Locale.negotiate(['de_DE', 'de'], ['en_US'])
+ assert nothing is None
+
+
+def test_negotiate_custom_separator():
+ de_DE = Locale.negotiate(['de-DE', 'de'], ['en-us', 'de-de'], sep='-')
+ assert (de_DE.language, de_DE.territory) == ('de', 'DE')
+
+
+def test_parse():
+ locale = Locale.parse('de-DE', sep='-')
+ assert locale.display_name == 'Deutsch (Deutschland)'
+
+ de_DE = Locale.parse(locale)
+ assert (de_DE.language, de_DE.territory) == ('de', 'DE')
+
+
+def test_parse_likely_subtags():
+ locale = Locale.parse('zh-TW', sep='-')
+ assert locale.language == 'zh'
+ assert locale.territory == 'TW'
+ assert locale.script == 'Hant'
+
+ locale = Locale.parse('zh_CN')
+ assert locale.language == 'zh'
+ assert locale.territory == 'CN'
+ assert locale.script == 'Hans'
+
+ locale = Locale.parse('zh_SG')
+ assert locale.language == 'zh'
+ assert locale.territory == 'SG'
+ assert locale.script == 'Hans'
+
+ locale = Locale.parse('und_AT')
+ assert locale.language == 'de'
+ assert locale.territory == 'AT'
+
+ locale = Locale.parse('und_UK')
+ assert locale.language == 'en'
+ assert locale.territory == 'GB'
+ assert locale.script is None
+
+
+def test_get_display_name():
+ zh_CN = Locale('zh', 'CN', script='Hans')
+ assert zh_CN.get_display_name('en') == 'Chinese (Simplified, China)'
+
+
+def test_display_name_property():
+ assert Locale('en').display_name == 'English'
+ assert Locale('en', 'US').display_name == 'English (United States)'
+ assert Locale('sv').display_name == 'svenska'
+
+
+def test_english_name_property():
+ assert Locale('de').english_name == 'German'
+ assert Locale('de', 'DE').english_name == 'German (Germany)'
+
+
+def test_languages_property():
+ assert Locale('de', 'DE').languages['ja'] == 'Japanisch'
+
+
+def test_scripts_property():
+ assert Locale('en', 'US').scripts['Hira'] == 'Hiragana'
+
+
+def test_territories_property():
+ assert Locale('es', 'CO').territories['DE'] == 'Alemania'
+
+
+def test_variants_property():
+ assert Locale('de', 'DE').variants['1901'] == 'Alte deutsche Rechtschreibung'
+
+
+def test_currencies_property():
+ assert Locale('en').currencies['COP'] == 'Colombian Peso'
+ assert Locale('de', 'DE').currencies['COP'] == 'Kolumbianischer Peso'
+
+
+def test_currency_symbols_property():
+ assert Locale('en', 'US').currency_symbols['USD'] == '$'
+ assert Locale('es', 'CO').currency_symbols['USD'] == 'US$'
+
+
+def test_number_symbols_property():
+ assert Locale('fr', 'FR').number_symbols["latn"]['decimal'] == ','
+ assert Locale('ar', 'IL').number_symbols["arab"]['percentSign'] == '٪\u061c'
+ assert Locale('ar', 'IL').number_symbols["latn"]['percentSign'] == '\u200e%\u200e'
+
+
+def test_other_numbering_systems_property():
+ assert Locale('fr', 'FR').other_numbering_systems['native'] == 'latn'
+ assert 'traditional' not in Locale('fr', 'FR').other_numbering_systems
+
+ assert Locale('el', 'GR').other_numbering_systems['native'] == 'latn'
+ assert Locale('el', 'GR').other_numbering_systems['traditional'] == 'grek'
+
+
+def test_default_numbering_systems_property():
+ assert Locale('en', 'GB').default_numbering_system == 'latn'
+ assert Locale('ar', 'EG').default_numbering_system == 'arab'
+
+
+@pytest.mark.all_locales
+def test_all_locales_have_default_numbering_system(locale):
+ locale = Locale.parse(locale)
+ assert locale.default_numbering_system
+
+
+def test_decimal_formats():
+ assert Locale('en', 'US').decimal_formats[None].pattern == '#,##0.###'
+
+
+def test_currency_formats_property():
+ en_us_currency_format = Locale('en', 'US').currency_formats
+ assert en_us_currency_format['standard'].pattern == '\xa4#,##0.00'
+ assert en_us_currency_format['accounting'].pattern == '\xa4#,##0.00;(\xa4#,##0.00)'
+
+
+def test_percent_formats_property():
+ assert Locale('en', 'US').percent_formats[None].pattern == '#,##0%'
+
+
+def test_scientific_formats_property():
+ assert Locale('en', 'US').scientific_formats[None].pattern == '#E0'
+
+
+def test_periods_property():
+ assert Locale('en', 'US').periods['am'] == 'AM'
+
+
+def test_days_property():
+ assert Locale('de', 'DE').days['format']['wide'][3] == 'Donnerstag'
+
+
+def test_months_property():
+ assert Locale('de', 'DE').months['format']['wide'][10] == 'Oktober'
+
+
+def test_quarters_property():
+ assert Locale('de', 'DE').quarters['format']['wide'][1] == '1. Quartal'
+
+
+def test_eras_property():
+ assert Locale('en', 'US').eras['wide'][1] == 'Anno Domini'
+ assert Locale('en', 'US').eras['abbreviated'][0] == 'BC'
+
+
+def test_time_zones_property():
+ time_zones = Locale('en', 'US').time_zones
+ assert time_zones['Europe/London']['long']['daylight'] == 'British Summer Time'
+ assert time_zones['America/St_Johns']['city'] == 'St. John\u2019s'
+
+
+def test_meta_zones_property():
+ meta_zones = Locale('en', 'US').meta_zones
+ assert meta_zones['Europe_Central']['long']['daylight'] == 'Central European Summer Time'
+
+
+def test_zone_formats_property():
+ assert Locale('en', 'US').zone_formats['fallback'] == '%(1)s (%(0)s)'
+ assert Locale('pt', 'BR').zone_formats['region'] == 'Hor\xe1rio %s'
+
+
+def test_first_week_day_property():
+ assert Locale('de', 'DE').first_week_day == 0
+ assert Locale('en', 'US').first_week_day == 6
+
+
+def test_weekend_start_property():
+ assert Locale('de', 'DE').weekend_start == 5
+
+
+def test_weekend_end_property():
+ assert Locale('de', 'DE').weekend_end == 6
+
+
+def test_min_week_days_property():
+ assert Locale('de', 'DE').min_week_days == 4
+
+
+def test_date_formats_property():
+ assert Locale('en', 'US').date_formats['short'].pattern == 'M/d/yy'
+ assert Locale('fr', 'FR').date_formats['long'].pattern == 'd MMMM y'
+
+
+def test_time_formats_property():
+ assert Locale('en', 'US').time_formats['short'].pattern == 'h:mm\u202fa'
+ assert Locale('fr', 'FR').time_formats['long'].pattern == 'HH:mm:ss z'
+
+
+def test_datetime_formats_property():
+ assert Locale('en').datetime_formats['full'] == "{1}, {0}"
+ assert Locale('th').datetime_formats['medium'] == '{1} {0}'
+
+
+def test_datetime_skeleton_property():
+ assert Locale('en').datetime_skeletons['Md'].pattern == "M/d"
+ assert Locale('th').datetime_skeletons['Md'].pattern == 'd/M'
+
+
+def test_plural_form_property():
+ assert Locale('en').plural_form(1) == 'one'
+ assert Locale('en').plural_form(0) == 'other'
+ assert Locale('fr').plural_form(0) == 'one'
+ assert Locale('ru').plural_form(100) == 'many'
+
+
+def test_locale_provides_access_to_cldr_locale_data():
+ locale = Locale('en', 'US')
+ assert locale.display_name == 'English (United States)'
+ assert locale.number_symbols["latn"]['decimal'] == '.'
+
+
+def test_locale_repr():
+ # fmt: off
+ assert repr(Locale('en', 'US')) == "Locale('en', territory='US')"
+ assert repr(Locale('de', 'DE')) == "Locale('de', territory='DE')"
+ assert repr(Locale('zh', 'CN', script='Hans')) == "Locale('zh', territory='CN', script='Hans')"
+ # fmt: on
+
+
+def test_locale_comparison():
+ en_US = Locale('en', 'US')
+ en_US_2 = Locale('en', 'US')
+ fi_FI = Locale('fi', 'FI')
+ bad_en_US = Locale('en_US')
+ assert en_US == en_US
+ assert en_US == en_US_2
+ assert en_US != fi_FI
+ assert not (en_US != en_US_2)
+ assert en_US is not None
+ assert en_US != bad_en_US
+ assert fi_FI != bad_en_US
+
+
+def test_hash():
+ locale_a = Locale('en', 'US')
+ locale_b = Locale('en', 'US')
+ locale_c = Locale('fi', 'FI')
+ assert hash(locale_a) == hash(locale_b)
+ assert hash(locale_a) != hash(locale_c)
+
+
+def test_language_alt_official_not_used():
+ # If there exists an official and customary language name, the customary
+ # name should be used.
+ #
+ # For example, here 'Muscogee' should be used instead of 'Mvskoke':
+ # Muscogee
+ # Mvskoke
+
+ locale = Locale('mus')
+ assert locale.get_display_name() == 'Mvskoke'
+ assert locale.get_display_name(Locale('en')) == 'Muscogee'