k8o

DurationFormatで期間をlocaleに基づいて表現する

公開: 2025年3月14日(金)
更新: 2025年3月28日(金)
閲覧数22 views

Intl.DurationFormatはlocaleに応じた形式で期間を表現するIntlの新機能で、Baseline 2025で利用可能です。formatメソッドで文字列として期間を取得でき、formatToPartsメソッドでは各部分をオブジェクトの配列として取得できます。言語による期間の表現の違いを標準に従って簡単扱いましょう。

JavaScriptBaseline 2025IntlIntl.DurationFormat

はじめに

Firefox 136.0のリリースでIntlDurationFormatが2025年のBaselineに追加されました。 Intl.DurationFormatlocaleに基づいた書式設定で期間を表現するものです。

const duration = {
  years: 1,
  months: 2,
  weeks: 3,
  days: 3,
  hours: 4,
  minutes: 5,
  seconds: 6,
};

new Intl.DurationFormat('ja').format(duration);
// 1 年 2 か月 3 週間 3 日 4 時間 5 分 6 秒

GitHub - tc39/proposal-intl-duration-format

Contribute to tc39/proposal-intl-duration-format development by creating an account on GitHub.

github.com

Intl.DurationFormat

Intl.DurationFormatlocaleに応じた書式の期間を表示するためのオブジェクトです。 他のIntlオブジェクトと同じように静的メソッドとしてsupportedLocalesOf()やインスタンスメソッドresolvedOptions()を持っています。

localeに応じた期間の出力はIntlDurationFormatオブジェクトを作成して、format及びにformatToPartsメソッドで行います。

localeや書式設定はIntl.DurationFormatオブジェクトを作成するタイミングで設定します。

new Intl.DurationFormat('ja-JP', {
  style: 'long',
});

第一引数にlocaleを文字列や配列で渡し、第二引数でその他のオプションをオブジェクト形式で渡します。

オプションの全ては説明しませんが、styleで表示する期間の長さ、yearsmonths等で個別のstyleを決定、yearsDisplaymonthsDisplayなどで0の時の表示を決めます。

styleにはlongshortnarrowdigitalの4つがあります。localejaの場合、以下のような表示になります。

// long 1 年 2 か月 3 週間 3 日 4 時間 5 分 6 秒 7 ミリ秒 8 マイクロ秒 9 ナノ秒
// short 1 年 2 か月 3 週間 3 日 4 時間 5 分 6 秒 7 ms 8 μs 9 ns
// narrow 1y2m3w3d4h5m6s7ms8μs9ns
// digital 1 年 2 か月 3 週間 3 日 4:05:06.007008009

format

作成したIntl.DurationFormatオブジェクトに対してformatメソッドを呼び出すことで期間を表示します。 formatは対応している期間をオブジェクト形式で受け取ります。

const duration = {
  years: 1,
  months: 2,
  hours: 4,
  seconds: 6,
};

new Intl.DurationFormat('ja').format(duration);
// 1 年 2 か月 4 時間 6 秒

全ての期間を含める必要はありません。

言い忘れましたが、期間はyearsmonthsweeksdayshoursminutessecondsmillisecondsmicrosecondsnanosecondsの9つに対応しています。これらをformatに渡すオブジェクトのキーとして利用できます。

formatToParts

formatToPartsメソッドはformatメソッドと同じように期間を表示しますが、formatメソッドが文字列を返すのに対して、formatToPartsメソッドはオブジェクトの配列を返します。

const duration = {
  years: 1,
  months: 2,
  hours: 4,
  seconds: 6,
};

new Intl.DurationFormat('ja').formatToParts(duration);
// [
//     {
//         "type": "integer",
//         "value": "1",
//         "unit": "year"
//     },
//     {
//         "type": "literal",
//         "value": " ",
//         "unit": "year"
//     },
//     {
//         "type": "unit",
//         "value": "年",
//         "unit": "year"
//     },
//     {
//         "type": "literal",
//         "value": " "
//     },
//     {
//         "type": "integer",
//         "value": "2",
//         "unit": "month"
//     },
//     {
//         "type": "literal",
//         "value": " ",
//         "unit": "month"
//     },
//     {
//         "type": "unit",
//         "value": "か月",
//         "unit": "month"
//     },
//     {
//         "type": "literal",
//         "value": " "
//     },
//     {
//         "type": "integer",
//         "value": "4",
//         "unit": "hour"
//     },
//     {
//         "type": "literal",
//         "value": " ",
//         "unit": "hour"
//     },
//     {
//         "type": "unit",
//         "value": "時間",
//         "unit": "hour"
//     },
//     {
//         "type": "literal",
//         "value": " "
//     },
//     {
//         "type": "integer",
//         "value": "6",
//         "unit": "second"
//     },
//     {
//         "type": "literal",
//         "value": " ",
//         "unit": "second"
//     },
//     {
//         "type": "unit",
//         "value": "秒",
//         "unit": "second"
//     }
// ]

期間を元に自分なりの表示を作成する場合はこちらが便利です。 日本語でformatした場合スペースが気になるので、こちらを利用した方が見栄えが良いかもしれません。