Skip to content

Give Latvian Friday and Maltese Sunday their own day abbreviations - #1380

Open
Nishuuzz wants to merge 1 commit into
arrow-py:masterfrom
Nishuuzz:fix-ambiguous-day-abbreviations
Open

Nishuuzz wants to merge 1 commit into
arrow-py:masterfrom
Nishuuzz:fix-ambiguous-day-abbreviations

Conversation

@Nishuuzz

Copy link
Copy Markdown

Pull Request Checklist

Thank you for taking the time to improve Arrow! Before submitting your pull request, please check all appropriate boxes:

  • 🧪 Added tests for changed code.
  • 🛠️ All tests pass when run locally (run tox or make test to find out!).
  • 🧹 All linting checks pass when run locally (run tox -e lint or make lint to find out!).
  • 📚 Updated documentation for changed code.
  • ⏩ Code is up-to-date with the master branch.

If you have any questions about your code changes or any of the points above, please submit your questions along with the pull request and we will try our best to help!

Description of Changes

This is the locale data half of what I mentioned in #1379. Two locales give the
same day_abbreviation to two different weekdays:

# LatvianLocale
day_abbreviations = ["", "pi", "ot", "tr", "ce", "pi", "se", "sv"]
#                         ^^^ pirmdiena              ^^^ piektdiena

# MalteseLocale
day_abbreviations = ["", "T", "TL", "E", "Ħ", "Ġ", "S", "Ħ"]
#                                        ^^^ Il-Ħamis       ^^^ Il-Ħadd

parser.py resolves the ddd token with
[x.lower() for x in self.locale.day_abbreviations].index(value), and
list.index returns the first match, so the second day of each pair is
unreachable. Formatting a weekday and parsing it straight back does not round
trip:

lv   iso  day name       ddd   parses back as
     1    pirmdiena      pi    1
     4    ceturtdiena    ce    4
     5    piektdiena     pi    1    <- should be 5
     7    svētdiena      sv    7

mt   iso  day name       ddd   parses back as
     3    L-Erbgħa       E     3
     4    Il-Ħamis       Ħ     4
     6    Is-Sibt        S     6
     7    Il-Ħadd        Ħ     4    <- should be 7

The change

For Latvian, the abbreviations are the first two letters of each name, and
piektdiena collides with pirmdiena. Latvian's own short forms break the tie
at the "k" — CLDR uses P O T C Pk S Sv for the narrow day names — so
piektdiena becomes "pk". That is the same reasoning the locale already
applies to svētdiena, which takes "sv" rather than colliding with
sestdiena's "se".

For Maltese, Il-Ħamis and Il-Ħadd are identical for their first two
letters, so one extra letter is not enough and they become "Ħam" and
"Ħad". CLDR's abbreviated Maltese forms separate them at the same point,
Il-Ħam and Il-Ħad. The locale already mixes abbreviation lengths for
exactly this reason, with "TL" for It-Tlieta against "T" for It-Tnejn,
so this follows what is there rather than introducing a new convention.

I kept the change to the two colliding entries. Restyling Maltese to CLDR's
full three-letter set (Tne Tli Erb Ħam Ġim Sib Ħad) would be more uniform,
but it touches days that are not broken, so I would rather do that separately
if you want it at all.

Worth flagging one behavioural consequence: "Ħ" on its own is no longer a
Maltese day abbreviation, so anything that stored that string will no longer
parse. It could not be parsed as Sunday before anyway, and it was ambiguous by
construction, so I think that is the right trade — but it is a change, not
purely additive.

Verification

The round trip above is the test: for each of the fourteen weekdays across the
two locales, format("ddd") then get(..., "ddd"). Before the change two of
the fourteen come back as the wrong day; after it all fourteen are correct.

The new test_day_abbreviations in each locale's test class pins every weekday
and also asserts the seven abbreviations are distinct, so a future edit that
reintroduces a collision fails rather than silently making a day unparseable.
Both tests fail on master:

>       assert self.locale.day_abbreviation(5) == "pk"
E       AssertionError: assert 'pi' == 'pk'

>       assert self.locale.day_abbreviation(4) == "Ħam"
E       AssertionError: assert 'Ħ' == 'Ħam'

pytest tests/ goes from 1901 to 1903 passing, 1 skipped, coverage 99.93%,
nothing failing either before or after. The existing test_weekday for both
locales checks Saturday, which neither change touches.

This is independent of #1379 and touches a different file, so the two do not
conflict and either can land first. #1379 does not fix these two and this does
not fix what #1379 fixes. The third collision I found, Sinhala's "බදා" for
both Tuesday and Wednesday, is in #1336 and I have left it alone here.

On the two unchecked boxes: I could not run make lint, because it drives
pre-commit and neither that nor isort installs in this environment. I ran
black --check and flake8, both clean, and the change touches no imports. No
documentation change seemed needed for a locale data correction, but say the
word if you would like a changelog entry.

Both locales list the same day_abbreviation for two different weekdays.
Latvian has "pi" for pirmdiena and piektdiena, and Maltese has "Ħ" for
Il-Ħamis and Il-Ħadd. The parser resolves ddd with list.index(), which
returns the first match, so the second of each pair cannot be parsed:
formatting Friday in lv and then parsing it back gives Monday, and the
same round trip in mt turns Sunday into Thursday.

Latvian already uses the two-letter forms that distinguish the days,
so piektdiena takes "pk". Maltese Ħamis and Ħadd only differ from the
third letter, so they take "Ħam" and "Ħad"; the locale already mixes
lengths for the same reason, with "TL" for Tlieta against "T" for Tnejn.
@codecov

codecov Bot commented Oct 13, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (2224255) to head (3aaaf9e).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff            @@
##            master     #1380   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           10        10           
  Lines         2315      2315           
  Branches       358       358           
=========================================
  Hits          2315      2315           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

@Wkhanex Wkhanex left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked formatter/parser roundtrips for all seven weekday abbreviations in Latvian and Maltese. The changed Friday/Sunday spellings now select their own weekday rather than a previously duplicated abbreviation, and formatting agrees with parsing.

Checked 3aaaf9ecc969 with standalone Python 3.12.14 checks (28 passing assertions). I haven't run the full upstream suite.

@Nishuuzz

Copy link
Copy Markdown
Author

A note for whoever picks this up, so the red X doesn't cost anyone time.

The windows-latest (pypy-3.11) failure is not from this change. The job dies installing pyyaml from its sdist during pip install -r requirements/requirements-tests.txt, so the tests never run — which is where the "No JUnit XML reports found" further down comes from. #1393 diagnoses it as a truncated pyyaml download stuck in the shared Windows pip cache, failing on master since September, and fixes it by putting the Python version in the cache key. Once that lands this should go green on a re-run. The other 26 checks pass.

On scope, since "why only these two locales" is the obvious question: I checked all 81 locales for weekday or month names and abbreviations that repeat within a single locale. A repeat is unparseable rather than merely untidy, because the parser builds one alternation and the name is looked up by index, so the later day can never be matched. Latvian and Maltese here are the only locales affected, apart from Sinhala, whose day_abbreviations are shifted out of alignment and which #1336 covers. Nothing has a wrong list length or a blank entry. So this isn't a spot fix with more of the same queued behind it.

Both spellings also match CLDR, if that helps as a second opinion. lv gives the short weekdays as Sv Pr Ot Tr Ce Pk Se, so pk for piektdiena is the conventional form and is precisely why it stops colliding with pirmdiena; mt needs three letters to separate Il-Ħamis from Il-Ħadd.

One deliberate omission: I left Latvian Monday as pi although CLDR's short form is Pr. It is a valid prefix of pirmdiena and it is not a duplicate, so it seemed out of scope for this fix — happy to change it if you would rather the locale matched CLDR throughout.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants