Python Babel Localization — Core Concepts
Babel is a Python library for locale-aware formatting and translation tooling. While gettext handles text translation, Babel handles everything else that varies by region: dates, numbers, currencies, time zones, and list formatting.
Installation
pip install Babel
Formatting Dates
from babel.dates import format_date, format_datetime
from datetime import date, datetime
d = date(2026, 3, 28)
format_date(d, locale="en_US") # "Mar 28, 2026"
format_date(d, locale="de_DE") # "28.03.2026"
format_date(d, locale="ja_JP") # "2026/03/28"
format_date(d, format="full", locale="fr_FR") # "samedi 28 mars 2026"
Format options: short, medium (default), long, full, or a custom skeleton.
Formatting Numbers
from babel.numbers import format_number, format_decimal
format_number(1234567, locale="en_US") # "1,234,567"
format_number(1234567, locale="de_DE") # "1.234.567"
format_number(1234567, locale="hi_IN") # "12,34,567" (Indian grouping)
Formatting Currency
from babel.numbers import format_currency
format_currency(1099.99, "USD", locale="en_US") # "$1,099.99"
format_currency(1099.99, "EUR", locale="de_DE") # "1.099,99\xa0€"
format_currency(1099.99, "JPY", locale="ja_JP") # "¥1,100" (JPY has no decimals)
Notice that Babel knows JPY doesn’t use decimal places — it rounds automatically.
Time Zones
from babel.dates import format_datetime, get_timezone
from datetime import datetime
tz = get_timezone("America/New_York")
dt = datetime(2026, 3, 28, 14, 30, tzinfo=tz)
format_datetime(dt, locale="en_US", tzinfo=tz)
# "Mar 28, 2026, 2:30:00 PM"
Locale Objects
A Locale object gives you metadata about any locale:
from babel import Locale
loc = Locale("pt", "BR")
loc.get_display_name("en") # "Portuguese (Brazil)"
loc.get_display_name("pt_BR") # "português (Brasil)"
loc.character_order # "left-to-right"
loc.script_name # "Latin"
Translation Extraction with Babel
Babel includes pybabel, a CLI tool that replaces GNU xgettext for Python projects:
# Extract translatable strings
pybabel extract -F babel.cfg -o messages.pot src/
# Create a new language catalog
pybabel init -l fr -d locales -i messages.pot
# Update existing catalogs after code changes
pybabel update -d locales -i messages.pot
# Compile .po → .mo
pybabel compile -d locales
A typical babel.cfg:
[python: src/**.py]
[jinja2: templates/**.html]
encoding = utf-8
Common Misconception
“Babel and gettext are competitors.” They’re complementary. gettext translates text strings. Babel formats locale-specific data (dates, numbers, currencies) and provides better extraction tools. Most production apps use both together.
How It Knows All This
Babel bundles CLDR (Unicode Common Locale Data Repository) — the same dataset used by ICU, Java, and browsers. CLDR covers 700+ locales with rules for number formatting, date patterns, currency symbols, plural categories, and more.
The one thing to remember: Babel formats dates, numbers, and currencies correctly for any locale using the CLDR standard — pair it with gettext for complete internationalization.
See Also
- Python Gettext I18n How Python's gettext module lets your app speak every language without rewriting a single line of logic.
- Python Locale Module Python's locale module reads your computer's regional settings so numbers, dates, and sorting feel right for where you live.
- Ci Cd Why big apps can ship updates every day without turning your phone into a glitchy mess — CI/CD is the behind-the-scenes quality gate and delivery truck.
- Containerization Why does software that works on your computer break on everyone else's? Containers fix that — and they're why Netflix can deploy 100 updates a day without the site going down.
- Python 310 New Features Python 3.10 gave programmers a shape-sorting machine, friendlier error messages, and cleaner ways to say 'this or that' in type hints.