From 49921e54e1cddc6db751d8e8ff32a16e116a8adf Mon Sep 17 00:00:00 2001 From: Parin Porecha Date: Wed, 22 Apr 2026 18:58:28 +0000 Subject: [PATCH 1/2] feat: add Gujarati (gu) localization support Add complete Gujarati locale with: - Day names (abbreviated, narrow, short, wide) - Month names (abbreviated, narrow, wide) - Unit translations (year, month, week, day, hour, minute, second, microsecond) - Relative time expressions (past and future) - Day periods (midnight, am, noon, pm, morning, afternoon, evening, night) - Custom translations for relative time strings and date formats - Full test coverage for diff_for_humans() Translations sourced from CLDR data via Babel library. Follows the same pattern as the Hindi (hi) locale added in #902. --- src/pendulum/locales/gu/__init__.py | 0 src/pendulum/locales/gu/custom.py | 21 +++ src/pendulum/locales/gu/locale.py | 221 ++++++++++++++++++++++++++++ tests/localization/test_gu.py | 69 +++++++++ 4 files changed, 311 insertions(+) create mode 100644 src/pendulum/locales/gu/__init__.py create mode 100644 src/pendulum/locales/gu/custom.py create mode 100644 src/pendulum/locales/gu/locale.py create mode 100644 tests/localization/test_gu.py diff --git a/src/pendulum/locales/gu/__init__.py b/src/pendulum/locales/gu/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/pendulum/locales/gu/custom.py b/src/pendulum/locales/gu/custom.py new file mode 100644 index 00000000..fca0b914 --- /dev/null +++ b/src/pendulum/locales/gu/custom.py @@ -0,0 +1,21 @@ +""" +gu custom locale file. +""" + +translations = { + "units": {"few_second": "અમુક સેકંડ"}, + # Relative time + "ago": "{} પહેલાં", + "from_now": "{} માં", + "after": "{0} પછી", + "before": "{0} પહેલાં", + # Date formats + "date_formats": { + "LTS": "h:mm:ss A", + "LT": "h:mm A", + "L": "DD/MM/YYYY", + "LL": "D MMMM YYYY", + "LLL": "D MMMM YYYY, h:mm A", + "LLLL": "dddd, D MMMM YYYY, h:mm A", + }, +} diff --git a/src/pendulum/locales/gu/locale.py b/src/pendulum/locales/gu/locale.py new file mode 100644 index 00000000..93e1839d --- /dev/null +++ b/src/pendulum/locales/gu/locale.py @@ -0,0 +1,221 @@ +from pendulum.locales.gu.custom import translations as custom_translations + + +""" +gu locale file. + +It has been generated automatically and must not be modified directly. +""" + + +locale = { + 'plural': lambda n: 'one' if ((n == n and ((n == 0))) or (n == n and ((n == 1)))) else 'other', + 'ordinal': lambda n: 'one', + 'translations': { + 'days': { + 'abbreviated': { + 0: 'રવિ', + 1: 'સોમ', + 2: 'મંગળ', + 3: 'બુધ', + 4: 'ગુરુ', + 5: 'શુક્ર', + 6: 'શનિ', + }, + 'narrow': { + 0: 'ર', + 1: 'સો', + 2: 'મં', + 3: 'બુ', + 4: 'ગુ', + 5: 'શુ', + 6: 'શ', + }, + 'short': { + 0: 'ર', + 1: 'સો', + 2: 'મં', + 3: 'બુ', + 4: 'ગુ', + 5: 'શુ', + 6: 'શ', + }, + 'wide': { + 0: 'રવિવાર', + 1: 'સોમવાર', + 2: 'મંગળવાર', + 3: 'બુધવાર', + 4: 'ગુરુવાર', + 5: 'શુક્રવાર', + 6: 'શનિવાર', + }, + }, + 'months': { + 'abbreviated': { + 1: 'જાન્યુ', + 2: 'ફેબ્રુ', + 3: 'માર્ચ', + 4: 'એપ્રિલ', + 5: 'મે', + 6: 'જૂન', + 7: 'જુલાઈ', + 8: 'ઑગસ્ટ', + 9: 'સપ્ટે', + 10: 'ઑક્ટો', + 11: 'નવે', + 12: 'ડિસે', + }, + 'narrow': { + 1: 'જા', + 2: 'ફે', + 3: 'મા', + 4: 'એ', + 5: 'મે', + 6: 'જૂ', + 7: 'જુ', + 8: 'ઑ', + 9: 'સ', + 10: 'ઑ', + 11: 'ન', + 12: 'ડિ', + }, + 'wide': { + 1: 'જાન્યુઆરી', + 2: 'ફેબ્રુઆરી', + 3: 'માર્ચ', + 4: 'એપ્રિલ', + 5: 'મે', + 6: 'જૂન', + 7: 'જુલાઈ', + 8: 'ઑગસ્ટ', + 9: 'સપ્ટેમ્બર', + 10: 'ઑક્ટોબર', + 11: 'નવેમ્બર', + 12: 'ડિસેમ્બર', + }, + }, + 'units': { + 'year': { + 'one': '{0} વર્ષ', + 'other': '{0} વર્ષ', + }, + 'month': { + 'one': '{0} મહિનો', + 'other': '{0} મહિના', + }, + 'week': { + 'one': '{0} અઠવાડિયું', + 'other': '{0} અઠવાડિયા', + }, + 'day': { + 'one': '{0} દિવસ', + 'other': '{0} દિવસ', + }, + 'hour': { + 'one': '{0} કલાક', + 'other': '{0} કલાક', + }, + 'minute': { + 'one': '{0} મિનિટ', + 'other': '{0} મિનિટ', + }, + 'second': { + 'one': '{0} સેકંડ', + 'other': '{0} સેકંડ', + }, + 'microsecond': { + 'one': '{0} માઇક્રોસેકંડ', + 'other': '{0} માઇક્રોસેકંડ', + }, + }, + 'relative': { + 'year': { + 'future': { + 'other': '{0} વર્ષમાં', + 'one': '{0} વર્ષમાં', + }, + 'past': { + 'other': '{0} વર્ષ પહેલાં', + 'one': '{0} વર્ષ પહેલાં', + }, + }, + 'month': { + 'future': { + 'other': '{0} મહિનામાં', + 'one': '{0} મહિનામાં', + }, + 'past': { + 'other': '{0} મહિના પહેલાં', + 'one': '{0} મહિના પહેલાં', + }, + }, + 'week': { + 'future': { + 'other': '{0} અઠવાડિયામાં', + 'one': '{0} અઠવાડિયામાં', + }, + 'past': { + 'other': '{0} અઠવાડિયા પહેલાં', + 'one': '{0} અઠવાડિયા પહેલાં', + }, + }, + 'day': { + 'future': { + 'other': '{0} દિવસમાં', + 'one': '{0} દિવસમાં', + }, + 'past': { + 'other': '{0} દિવસ પહેલાં', + 'one': '{0} દિવસ પહેલાં', + }, + }, + 'hour': { + 'future': { + 'other': '{0} કલાકમાં', + 'one': '{0} કલાકમાં', + }, + 'past': { + 'other': '{0} કલાક પહેલાં', + 'one': '{0} કલાક પહેલાં', + }, + }, + 'minute': { + 'future': { + 'other': '{0} મિનિટમાં', + 'one': '{0} મિનિટમાં', + }, + 'past': { + 'other': '{0} મિનિટ પહેલાં', + 'one': '{0} મિનિટ પહેલાં', + }, + }, + 'second': { + 'future': { + 'other': '{0} સેકંડમાં', + 'one': '{0} સેકંડમાં', + }, + 'past': { + 'other': '{0} સેકંડ પહેલાં', + 'one': '{0} સેકંડ પહેલાં', + }, + }, + }, + 'day_periods': { + "midnight": "મધ્યરાત્રિ", + "am": "AM", + "noon": "બપોર", + "pm": "PM", + "morning1": "સવારે", + "afternoon1": "બપોરે", + "evening1": "સાંજે", + "night1": "રાત્રે", + }, + 'week_data': { + 'min_days': 1, + 'first_day': 0, + 'weekend_start': 5, + 'weekend_end': 6, + }, + }, + 'custom': custom_translations +} diff --git a/tests/localization/test_gu.py b/tests/localization/test_gu.py new file mode 100644 index 00000000..86399701 --- /dev/null +++ b/tests/localization/test_gu.py @@ -0,0 +1,69 @@ +from __future__ import annotations + +import pendulum + + +locale = "gu" + + +def test_diff_for_humans(): + with pendulum.travel_to(pendulum.datetime(2025, 6, 4), freeze=True): + diff_for_humans() + + +def diff_for_humans(): + d = pendulum.now().subtract(seconds=1) + assert d.diff_for_humans(locale=locale) == "અમુક સેકંડ પહેલાં" + + d = pendulum.now().subtract(seconds=2) + assert d.diff_for_humans(locale=locale) == "અમુક સેકંડ પહેલાં" + + d = pendulum.now().subtract(seconds=21) + assert d.diff_for_humans(locale=locale) == "21 સેકંડ પહેલાં" + + d = pendulum.now().subtract(minutes=1) + assert d.diff_for_humans(locale=locale) == "1 મિનિટ પહેલાં" + + d = pendulum.now().subtract(minutes=2) + assert d.diff_for_humans(locale=locale) == "2 મિનિટ પહેલાં" + + d = pendulum.now().subtract(hours=1) + assert d.diff_for_humans(locale=locale) == "1 કલાક પહેલાં" + + d = pendulum.now().subtract(hours=2) + assert d.diff_for_humans(locale=locale) == "2 કલાક પહેલાં" + + d = pendulum.now().subtract(days=1) + assert d.diff_for_humans(locale=locale) == "1 દિવસ પહેલાં" + + d = pendulum.now().subtract(days=2) + assert d.diff_for_humans(locale=locale) == "2 દિવસ પહેલાં" + + d = pendulum.now().subtract(weeks=1) + assert d.diff_for_humans(locale=locale) == "1 અઠવાડિયા પહેલાં" + + d = pendulum.now().subtract(weeks=2) + assert d.diff_for_humans(locale=locale) == "2 અઠવાડિયા પહેલાં" + + d = pendulum.now().subtract(months=1) + assert d.diff_for_humans(locale=locale) == "1 મહિના પહેલાં" + + d = pendulum.now().subtract(months=2) + assert d.diff_for_humans(locale=locale) == "2 મહિના પહેલાં" + + d = pendulum.now().subtract(years=1) + assert d.diff_for_humans(locale=locale) == "1 વર્ષ પહેલાં" + + d = pendulum.now().subtract(years=2) + assert d.diff_for_humans(locale=locale) == "2 વર્ષ પહેલાં" + + d = pendulum.now().add(seconds=1) + assert d.diff_for_humans(locale=locale) == "અમુક સેકંડ માં" + + d = pendulum.now().add(seconds=1) + d2 = pendulum.now() + assert d.diff_for_humans(d2, locale=locale) == "અમુક સેકંડ પછી" + assert d2.diff_for_humans(d, locale=locale) == "અમુક સેકંડ પહેલાં" + + assert d.diff_for_humans(d2, True, locale=locale) == "અમુક સેકંડ" + assert d2.diff_for_humans(d.add(seconds=1), True, locale=locale) == "અમુક સેકંડ" From 07f7cb3ff95d6ea65e729c5ab857472d827bedf2 Mon Sep 17 00:00:00 2001 From: Parin Porecha Date: Wed, 22 Apr 2026 19:21:34 +0000 Subject: [PATCH 2/2] [verified] fix: correct Gujarati weekday indexing --- src/pendulum/locales/gu/locale.py | 56 +++++++++++++++---------------- tests/localization/test_gu.py | 7 ++++ 2 files changed, 35 insertions(+), 28 deletions(-) diff --git a/src/pendulum/locales/gu/locale.py b/src/pendulum/locales/gu/locale.py index 93e1839d..4049ad1c 100644 --- a/src/pendulum/locales/gu/locale.py +++ b/src/pendulum/locales/gu/locale.py @@ -14,40 +14,40 @@ 'translations': { 'days': { 'abbreviated': { - 0: 'રવિ', - 1: 'સોમ', - 2: 'મંગળ', - 3: 'બુધ', - 4: 'ગુરુ', - 5: 'શુક્ર', - 6: 'શનિ', + 0: 'સોમ', + 1: 'મંગળ', + 2: 'બુધ', + 3: 'ગુરુ', + 4: 'શુક્ર', + 5: 'શનિ', + 6: 'રવિ', }, 'narrow': { - 0: 'ર', - 1: 'સો', - 2: 'મં', - 3: 'બુ', - 4: 'ગુ', - 5: 'શુ', - 6: 'શ', + 0: 'સો', + 1: 'મં', + 2: 'બુ', + 3: 'ગુ', + 4: 'શુ', + 5: 'શ', + 6: 'ર', }, 'short': { - 0: 'ર', - 1: 'સો', - 2: 'મં', - 3: 'બુ', - 4: 'ગુ', - 5: 'શુ', - 6: 'શ', + 0: 'સો', + 1: 'મં', + 2: 'બુ', + 3: 'ગુ', + 4: 'શુ', + 5: 'શ', + 6: 'ર', }, 'wide': { - 0: 'રવિવાર', - 1: 'સોમવાર', - 2: 'મંગળવાર', - 3: 'બુધવાર', - 4: 'ગુરુવાર', - 5: 'શુક્રવાર', - 6: 'શનિવાર', + 0: 'સોમવાર', + 1: 'મંગળવાર', + 2: 'બુધવાર', + 3: 'ગુરુવાર', + 4: 'શુક્રવાર', + 5: 'શનિવાર', + 6: 'રવિવાર', }, }, 'months': { diff --git a/tests/localization/test_gu.py b/tests/localization/test_gu.py index 86399701..1a2af877 100644 --- a/tests/localization/test_gu.py +++ b/tests/localization/test_gu.py @@ -67,3 +67,10 @@ def diff_for_humans(): assert d.diff_for_humans(d2, True, locale=locale) == "અમુક સેકંડ" assert d2.diff_for_humans(d.add(seconds=1), True, locale=locale) == "અમુક સેકંડ" + + +def test_format(): + d = pendulum.datetime(2016, 8, 29, 7, 3, 6, 123456) + assert d.format("dddd", locale=locale) == "સોમવાર" + assert d.format("ddd", locale=locale) == "સોમ" + assert d.format("dd", locale=locale) == "સો"