Skip to content

feat: locale-aware date, currency & number formatting (#131)#394

Open
sinatragian wants to merge 2 commits intorohitdash08:mainfrom
sinatragian:feat/locale-formatting
Open

feat: locale-aware date, currency & number formatting (#131)#394
sinatragian wants to merge 2 commits intorohitdash08:mainfrom
sinatragian:feat/locale-formatting

Conversation

@sinatragian
Copy link

@sinatragian sinatragian commented Mar 13, 2026

Adds locale-aware date, currency & number formatting to fix #131.

Pure-Python formatter (no extra deps). Supports format_currency, format_number, format_date, format_datetime with per-locale separators, symbol position, date patterns and time formats. Exposed via /locale/ endpoints.


Review fixes (latest commit)

  1. Lakh (South-Asian) grouping for en_IN / hi_IN — the original _format_number_parts always used groups of 3, producing 1,234,567 instead of the correct 12,34,567 (rightmost group = 3 digits, all subsequent groups = 2 digits). Fixed by adding a lakh: bool field to _LOCALE_META for each locale and a branching path in _format_number_parts that applies the 3-2-2-… algorithm when lakh=True. format_currency and format_number both propagate the flag.

    • 1234567 (en_IN) → 12,34,567
    • 100000 (en_IN) → 1,00,000
    • 1234567 (en_US) → 1,234,567 unchanged ✓
  2. Locale-aware 12h/24h time format in format_datetime — was hard-coded to %I:%M %p (12-hour AM/PM) for every locale. Added a time field to every _LOCALE_META entry: %I:%M %p for en_* locales; %H:%M for de_DE, fr_FR, it_IT, es_ES, pt_BR, ja_JP, zh_CN, ar_SA. format_datetime now reads meta['time'].

New tests (13 added):

  • Lakh: test_inr_en_in_lakh, test_inr_hi_in_lakh, test_en_in_lakh_grouping_large/medium/small/below_1000, test_hi_in_lakh_grouping, test_en_us_not_lakh
  • Time format: test_en_us_12h_format, test_en_in_12h_format, test_de_de_24h_format, test_fr_fr_24h_format, test_ja_jp_24h_format, test_zh_cn_24h_format

Closes #131

- services/locale_fmt.py: format_currency, format_number, format_date,
  format_datetime — pure Python, no extra deps, 13 locales supported
- routes/locale.py: GET /locale/supported, GET /locale/info,
  POST /locale/format, GET /locale/preview
- User.preferred_locale field (default en_IN)
- PATCH /auth/me now accepts preferred_locale
- GET /auth/me returns preferred_locale
- Migration 006_locale.sql
- 31 tests covering unit formatting + HTTP endpoints

Closes rohitdash08#131
Fix 1 — Lakh (South-Asian) number grouping for en_IN and hi_IN
  The original _format_number_parts always used groups of 3, producing
  standard Western formatting (1,234,567) instead of the correct Indian
  system (12,34,567 — rightmost group is 3 digits, all subsequent groups
  are 2 digits).

  Added lakh: bool to _LOCALE_META entries for en_IN and hi_IN (True) and
  all other locales (False, explicit).  _format_number_parts now accepts a
  lakh kwarg and applies the 3-2-2-... grouping when True.  format_currency
  and format_number both pass the flag through from metadata.

  Examples:
    1234567  (en_IN) → 12,34,567    (was 1,234,567)
    100000   (en_IN) → 1,00,000     (was 1,00,000 — coincidence for 6 digits, but
                                      1234567 was wrong before)
    1234567  (en_US) → 1,234,567    (unchanged)

Fix 2 — Locale-aware 12h/24h time format in format_datetime
  format_datetime previously hard-coded '%I:%M %p' (12-hour with AM/PM)
  for every locale, including de_DE, fr_FR, ja_JP, zh_CN which conventionally
  use 24-hour time.

  Added time: str field to every _LOCALE_META entry ('%I:%M %p' for en_*
  locales, '%H:%M' for European/Asian locales).  format_datetime now reads
  meta['time'] instead of the hard-coded string.

Tests added / updated:
  - test_inr_en_in: tightened to verify standard 4-digit amount still works
  - test_inr_en_in_lakh: 1234567.89 → ₹12,34,567.89
  - test_inr_hi_in_lakh: 100000 → ₹1,00,000.00
  - test_en_in_lakh_grouping_large/medium/small/below_1000
  - test_hi_in_lakh_grouping, test_en_us_not_lakh
  - test_en_us_12h_format, test_en_in_12h_format
  - test_de_de_24h_format, test_fr_fr_24h_format
  - test_ja_jp_24h_format, test_zh_cn_24h_format
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.

Locale-aware date, currency & number formatting

1 participant