DEV Community

loading...
Doctolib Engineering

Painless i18n for Moment.js

coisnepe profile image Paul-Etienne Coisne ・2 min read

You serve a multi-lingual JS app, use Moment.js and need to internationalize how times are displayed? Why bother with an expansive new NPM package where you could do it yourself in just a few lines of code?

First create a file that'll store the various formats you need, as well as the function that'll pass them to your custom Moment.js localize function:

// First find a way to determine the user's locale
const getLocale = () => window.locale || 'fr'

// Define as many formats as you wish.
const formats = {
  'ddd DD': {
    fr: 'ddd DD',
    de: 'ddd Do',
    en: 'ddd Do',
    'en-US': 'ddd Do',
    it: 'ddd DD',
  },
  'D MMM YYYY à HH:mm': {
    fr: 'D MMM YYYY à HH:mm',
    de: 'Do MMM YYYY [um] H:mm',
    en: 'D MMM YYYY [at] H:mm',
    'en-US': 'MMM Do YYYY [at] H:mm',
    it: 'D MMM YYYY [alle] HH:mm',
  },
}

// Whether you want the function to fail or not if the name doesn't exist is up to you. 
const i18nFormat = (name, locale = getLocale()) => {
  if (typeof formats[name] !== 'object') {
    console.log(`Unknown format definition for "${name}"`)

    return name
  }

  if (!formats[name][locale]) {
    console.log(
      false,
      `Missing format definition for "${name}" in locale "${locale}"`
    )

    return name
  }

  return formats[name][locale]
}

export default i18nFormat
Enter fullscreen mode Exit fullscreen mode

Now you can create a file defining your localize function...

import moment from 'moment'

moment.fn.localize = function localize(inputString) {
  return this.format(i18nFormats(inputString))
}
Enter fullscreen mode Exit fullscreen mode

...and import it at the root of your project. You're hot to trot!

import React from 'react'
import './setupMoment'
import moment from 'moment'

const App = () => (
  <div className="App">
    <h1>Internationalize Moment.js the easy way</h1>
    <h2>'dddd': {moment().localize('dddd')}</h2>
    <h2>'D MMM YYYY à HH:mm': {moment().localize('D MMM YYYY à HH:mm')}</h2>
  </div>
)

export default App
Enter fullscreen mode Exit fullscreen mode

Functional demo on Codesandbox

Discussion (0)

pic
Editor guide