Repository: django/django

Issue:
# Fixed #36679 -- Fixed Basque date formats to use parenthetical declension suffixes.

#### Trac ticket number
<!-- Replace XXXXX with the corresponding Trac ticket number. -->
<!-- Or delete the line and write "N/A" if this is a trivial PR. -->

ticket-36679

#### Branch description
Basque (eu) grammar requires conditional suffixes on years and day articles that depend on the final sound of the preceding word. Since Django's format strings are static, the CLDR parenthetical convention ("(e)ko" instead of "ko") is used to express the optionality.

This is a revamp of #19988.

#### AI Assistance Disclosure (REQUIRED)
<!-- Please select exactly ONE of the following: -->
- [ ] **No AI tools were used** in preparing this PR.
- [X] **If AI tools were used**, I have disclosed which ones, and fully reviewed and verified their output.

Claude code with model Sonnet 4.6 was used to analyze and summarize the [forum post](https://forum.djangoproject.com/t/basque-date-declination/43205) and [related ticket](https://code.djangoproject.com/ticket/36679).

#### Checklist
- [X] This PR follows the [contribution guidelines](https://docs.djangoproject.com/en/stable/internals/contributing/writing-code/submitting-patches/).
- [X] This PR **does not** disclose a security vulnerability (see [vulnerability reporting](https://docs.djangoproject.com/en/stable/internals/security/)).
- [X] This PR targets the `main` branch. <!-- Backports will be evaluated and done by mergers, when necessary. -->
- [X] The commit message is written in past tense, mentions the ticket number, and ends with a period.
- [X] I have checked the "Has patch" ticket flag in the Trac system.
- [X] I have added or updated relevant tests.
- [ ] I have added or updated relevant docs, including release notes if applicable.
- [ ] I have attached screenshots in both light and dark modes for any UI changes.


Implementation patch:
diff --git a/django/conf/locale/eu/formats.py b/django/conf/locale/eu/formats.py
index 61b16fbc6f69..e707f931c70c 100644
--- a/django/conf/locale/eu/formats.py
+++ b/django/conf/locale/eu/formats.py
@@ -2,10 +2,10 @@
 #
 # The *_FORMAT strings use the Django date format syntax,
 # see https://docs.djangoproject.com/en/dev/ref/templates/builtins/#date
-DATE_FORMAT = r"Y\k\o N j\a"
+DATE_FORMAT = r"Y(\e)\k\o N\k j"
 TIME_FORMAT = "H:i"
-DATETIME_FORMAT = r"Y\k\o N j\a, H:i"
-YEAR_MONTH_FORMAT = r"Y\k\o F"
+DATETIME_FORMAT = r"Y(\e)\k\o N\k j, H:i"
+YEAR_MONTH_FORMAT = r"Y(\e)\k\o F"
 MONTH_DAY_FORMAT = r"F\r\e\n j\a"
 SHORT_DATE_FORMAT = "Y-m-d"
 SHORT_DATETIME_FORMAT = "Y-m-d H:i"


Test patch:
diff --git a/tests/i18n/tests.py b/tests/i18n/tests.py
index e593d97cba14..91e7c95f67a0 100644
--- a/tests/i18n/tests.py
+++ b/tests/i18n/tests.py
@@ -1179,6 +1179,26 @@ def test_uncommon_locale_formats(self):
                 with translation.override(locale, deactivate=True):
                     self.assertEqual(expected, format_function(*format_args))
 
+    def test_basque_date_formats(self):
+        # Basque locale uses parenthetical suffixes for conditional declension:
+        # (e)ko for years and declined month/day forms.
+        with translation.override("eu", deactivate=True):
+            self.assertEqual(date_format(self.d), "2009(e)ko abe.k 31")
+            self.assertEqual(
+                date_format(self.dt, "DATETIME_FORMAT"),
+                "2009(e)ko abe.k 31, 20:50",
+            )
+            self.assertEqual(
+                date_format(self.d, "YEAR_MONTH_FORMAT"), "2009(e)ko abendua"
+            )
+            self.assertEqual(date_format(self.d, "MONTH_DAY_FORMAT"), "abenduaren 31a")
+            # Day 11 (hamaika in Basque) ends in 'a' as a word, but the
+            # numeral form does not, so appending 'a' is correct here.
+            self.assertEqual(
+                date_format(datetime.date(2009, 12, 11), "MONTH_DAY_FORMAT"),
+                "abenduaren 11a",
+            )
+
     def test_sub_locales(self):
         """
         Check if sublocales fall back to the main locale