Skip to content

datetime and number

vue-i18n's d() and n(). Both need the intl extra:

sh
pip install "vue-i18n-python[intl]"
python
from vue_i18n import datetime as d, number as n

These do not match Intl character for character

Everything around the format is a port: the argument shapes, the named formats, the fallback walk, the missing handling, the override merging and the cache. The formatting itself cannot be — Intl.DateTimeFormat and Intl.NumberFormat do not exist in Python, so babel stands in, and the two carry different CLDR data versions.

Month names and separators may differ from the browser. If a string must be byte-identical on both ends, format it on one end and send it.

Named formats

Declare them on the context, the same objects a Vue application passes:

python
short_date = {"year": "numeric", "month": "short", "day": "numeric"}

ctx = create_core_context(
    locale="de",
    fallback_locale="en",
    number_formats={
        "de": {"currency": {"style": "currency", "currency": "EUR"}},
        "en-US": {"currency": {"style": "currency", "currency": "USD"}},
        "ja": {"currency": {"style": "currency", "currency": "JPY"}},
    },
    datetime_formats={loc: {"short": short_date} for loc in ("de", "en-US", "ja")},
)

One format object, three locales — which is the whole reason these calls take a locale rather than a pattern:

python
n(ctx, 1234.5, "currency")              # '1.234,50 €'
n(ctx, 1234.5, "currency", "en-US")     # '$1,234.50'
n(ctx, 1234.5, "currency", "ja")        # '¥1,234'      - no minor unit for JPY

d(ctx, moment, "short")                 # '12. Aug. 2026'
d(ctx, moment, "short", "en-US")        # 'Aug 12, 2026'
d(ctx, moment, "short", "ja")           # '2026年8月12日'

Note the separator in 1.234,50 €: that is a non-breaking space before the symbol, not an ordinary one, which is the kind of detail the warning above is about. Compare with == rather than by eye.

A named format is looked up through the fallback chain, so a format defined only in en is found from a de context.

Call shapes

python
n(ctx, 1234.5)                                   # locale defaults
n(ctx, 1234.5, "currency")                       # a named format
n(ctx, 1234.5, "currency", "en")                 # named format, explicit locale
n(ctx, 1234.5, "currency", {"currency": "GBP"})  # named format with overrides
n(ctx, 1234.5, {"style": "percent"})             # options, no named format

d() takes the same shapes. Its value may be a datetime, a date, a POSIX timestamp in milliseconds (as Date does), or an ISO 8601 string.

Options that are honoured

Numbersstyle (decimal, percent, currency), currency, useGrouping, minimumIntegerDigits, minimumFractionDigits, maximumFractionDigits, notation: "compact" with compactDisplay.

DatesdateStyle and timeStyle (full, long, medium, short), the component options era, year, month, day, weekday, hour, minute, second, timeZoneName, plus hour12 and timeZone.

The component options are mapped onto a CLDR skeleton, which is what babel takes — so {"year": "numeric", "month": "short", "day": "numeric"} becomes yMMMd. That mapping is what lets a format object written for a Vue front end be read here unchanged.

Options that are ignored

Accepted and then dropped, because babel has nowhere to put them:

  • numberslocaleMatcher, currencySign, signDisplay, unit, unitDisplay, roundingMode, roundingPriority, roundingIncrement, trailingZeroDisplay, minimumSignificantDigits, maximumSignificantDigits
  • dateslocaleMatcher, formatMatcher, calendar, numberingSystem, hourCycle, fractionalSecondDigits

Ask rather than discover:

python
from vue_i18n.runtime.number import unsupported_number_options
from vue_i18n.runtime.datetime import unsupported_datetime_options

unsupported_number_options({"style": "decimal", "signDisplay": "always"})   # {'signDisplay'}

Not supported

part=True (formatToParts) raises NotImplementedError. babel has no counterpart, and a caller asking for parts wants the structure — an approximation would be worse than a refusal.

Missing formats

Same as translate: a format name that resolves nowhere returns the name, or NOT_RESOLVED when the context was built with unresolving=True. A non-numeric value to n() warns and returns the empty string rather than raising, which is upstream's behaviour.

Released under the MIT License. vue-i18n is © kazuya kawaguchi and contributors; this is an unofficial port and is not affiliated with intlify.