Skip to content

Localizing date and time

fluent-vue relies on Fluent syntax for formatting dates, numbers, etc. Fluent automatically selects a formatter for the argument and formats it using a given locale:

Today is { $date } -> Today is 4/5/2024

To allow greater control of date and time formatting, Fluent has a built-in function: DATETIME. It uses Intl.DateTimeFormat under the hood.

In most cases, localizers don't need to call the function explicitly, thanks to the implicit formatting. But if the implicit formatting is not sufficient, the function can be called explicitly with additional parameters. Both developers and localizers can pass parameters to it.

Specifying parameters by localizers:

Localizers can specify formatting options that are specific to the given locale.

ftl
today-is = Today is { DATETIME($date, month: "long", year: "numeric", day: "numeric") }
js
$t('today-is', { date: new Date() })

Result: Today is ⁨April 5, 2024⁩

Specifying parameters by developers:

The developer can annotate the argument with additional information on how to format it.

ftl
today-is = Today is { DATETIME($date, month: "long", year: "numeric", day: "numeric") }
js
$t('today-is', { date: new FluentDateTime(new Date(), { weekday: 'long' }) })

Result: Today is ⁨Friday, April 5, 2024⁩

If the localizer wishes to modify the parameters, for example, because the string doesn't fit in the UI, they can pass the variable to the same function and overload the parameters set by the developer.

Parameters:

Here is the list of most commonly used parameters:

dateStyle: [ 'full', 'long', 'medium', 'short' ]
timeStyle: [ 'full', 'long', 'medium', 'short' ]
month: [ 'numeric', '2-digit', 'long', 'short', 'narrow' ]
year: [ 'numeric', '2-digit' ]
weekday: [ 'long', 'short', 'narrow' ]
day, hour, minute, and second: [ 'numeric', '2-digit' ]

See the Intl.DateTimeFormat for the rest of the parameters and their description.

Example

vue
<template>
  <p class="demo">
    {{ $t('default', { now }) }}<br>
    {{ $t('today', { now }) }}<br>
    {{ $t('now', { now }) }}
  </p>
</template>

<fluent locale="en">
default = Current date: {{ $now }}
today = Today is {{ DATETIME($now, day: "numeric", month: "long", year: "numeric") }}
now = It is {{ DATETIME($now, hour: "numeric", minute: "numeric", second: "numeric") }}
</fluent>

Output

Current date: ⁨4/5/2024⁩
Today is ⁨April 5, 2024⁩
It is ⁨9:44:21 AM⁩

Using custom library for date formatting

If Intl.DateTimeFormat functionality is no sufficient, you can use a custom function for date and time formatting instead of using the built-in one.

Here is an example of using date-fns:

Add custom function to the bundle

js
import { format } from 'date-fns'

const bundle = new FluentBundle('en', {
  functions: {
    DATEFNS (positionalArgs, namedArgs) {
      const [date, formatString] = positionalArgs as [string, string]
      return format(new Date(date), formatString)
    }
  }
})

const fluent = createFluentVue({
  bundles: [bundle],
})

Use it

vue
<template>
  <p class="demo">
    {{ $t('default', { now }) }}<br>
    {{ $t('today', { now }) }}<br>
    {{ $t('now', { now }) }}
  </p>
</template>

<fluent locale="en">
default = Current date: {{ $now }}
today = Today is {{ DATEFNS($now, "PP") }}
now = It is {{ DATEFNS($now, "pp") }}
</fluent>

Output

Current date: ⁨4/5/2024⁩
Today is ⁨Apr 5, 2024⁩
It is ⁨9:44:21 AM⁩

MIT Licensed