Babel locale-aware number, currency and date formatting: working versions (tested 2026-10-16)
Format and parse numbers, currency and dates per locale with Babel, handling non-breaking spaces, currency-specific fraction digits and timezone conversion, all offline under pytest.
passed6 passed · 0 failed2026-10-16 09:57 UTC- Status
- passed
- Last passed
- 2026-10-16 09:57 UTC
- Tests
- 6 / 6
- Language
- Python
- Runtime
- Python 3.13.16
pinned versions2
babel@2.18.0pytest@9.1.1
run it
uv venv -q .venv && uv pip install -q --python .venv/bin/python -r requirements.txt .venv/bin/python -m pytest -q
test environment
Python 3.13.16 linux 6.17.0-1022-azure x64 runner: github-actions 38883899161
The code
Exactly the files that passed. Your agent can pull them with get_recipe("babel-locale-number-date-format") (install), or see them on GitHub.
requirements.txt
babel==2.18.0 pytest==9.1.1
money.py
from babel.dates import format_date, format_datetime
from babel.numbers import format_currency, format_decimal, parse_decimal
def format_price(amount, currency, locale):
return format_currency(amount, currency, locale=locale)
def format_quantity(value, locale):
return format_decimal(value, locale=locale)
def parse_price(text, locale):
return parse_decimal(text, locale=locale)
def format_day(value, locale):
return format_date(value, format="long", locale=locale)
def format_stamp(value, locale, tzinfo=None):
return format_datetime(value, format="short", locale=locale, tzinfo=tzinfo)
tests/test_money.py
from datetime import date, datetime, timezone
from decimal import Decimal
from zoneinfo import ZoneInfo
from money import format_day, format_price, format_quantity, format_stamp, parse_price
def normalise(text):
return text.replace("\u00a0", " ").replace("\u202f", " ")
def test_number_grouping_is_locale_specific():
assert format_quantity(1234567.891, "en_US") == "1,234,567.891"
assert format_quantity(1234567.891, "de_DE") == "1.234.567,891"
def test_currency_symbol_position_differs_by_locale():
assert format_price(1234.5, "USD", "en_US") == "$1,234.50"
assert normalise(format_price(1234.5, "USD", "de_DE")) == "1.234,50 $"
def test_currency_fraction_digits_follow_the_currency():
assert format_price(1234.5, "USD", "en_US") == "$1,234.50"
assert format_price(1234.5, "JPY", "ja_JP").endswith("1,234")
def test_parse_returns_decimal_and_depends_on_locale():
assert parse_price("1.234,56", "de_DE") == Decimal("1234.56")
assert parse_price("1,234.56", "en_US") == Decimal("1234.56")
# the wrong locale silently reinterprets the separators instead of erroring
assert parse_price("1,234.56", "de_DE") == Decimal("1.23456")
def test_dates_are_localised_per_locale():
day = date(2024, 3, 15)
assert format_day(day, "en_US") == "March 15, 2024"
assert format_day(day, "fr_FR") == "15 mars 2024"
assert format_day(day, "de_DE") == "15. M\u00e4rz 2024"
def test_datetime_is_converted_to_the_target_timezone():
stamp = datetime(2024, 3, 15, 12, 30, tzinfo=timezone.utc)
assert normalise(format_stamp(stamp, "en_US")) == "3/15/24, 12:30 PM"
assert normalise(format_stamp(stamp, "en_US", ZoneInfo("America/New_York"))) == "3/15/24, 8:30 AM"
assert format_stamp(stamp, "de_DE", ZoneInfo("Europe/Berlin")) == "15.03.24, 13:30"
pytest.ini
[pytest] pythonpath = .
Connect to ProvenPin
Add the free MCP server so your agent can pull this recipe and others like it. Same setup as the docs.
terminal
claude mcp add --transport http provenpin https://mcp.provenpin.com/mcp
~/.cursor/mcp.json
{ "mcpServers": { "provenpin": { "url": "https://mcp.provenpin.com/mcp" } } }.vscode/mcp.json
{ "servers": { "provenpin": { "type": "http", "url": "https://mcp.provenpin.com/mcp" } } }~/.codeium/windsurf/mcp_config.json
{ "mcpServers": { "provenpin": { "serverUrl": "https://mcp.provenpin.com/mcp" } } }MCP settings
{ "mcpServers": { "provenpin": { "type": "streamableHttp", "url": "https://mcp.provenpin.com/mcp" } } }Any other MCP client: Streamable HTTP at https://mcp.provenpin.com/mcp. No API key, no signup.