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.

pythonbabellocalizationl10nformatting

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.