10
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Intl.DateTimeFormatでロケールに応じて日付をフォーマットする

Posted at

ロケールごとの日付表記の違い

プログラムで取り扱う日付文字列は 2020-01-01 2020/01/01 といった「ゼロパディング、ハイフン or スラッシュ区切り」などがありますが、ユーザーフレンドリーにするため以下のような形式で表記することがあるかと思います。

  • 1月1日(水)
  • Jan 1(Wed)

例えばmoment.jsを利用すると以下のようになります。

moment.locale('ja');
moment('2020-01-01').format('M月D日(ddd)')
// > "1月1日(水)"

moment.locale('en');
moment('2020-01-01').format('MMM D(ddd)');
// > "Jan 1(Wed)"

自由な書式フォーマットの指定ができるので便利ですが、日付の計算や比較をするわけでもなく、ただフォーマットするだけであれば、標準APIであるIntl.DateTimeFormatを使うという選択肢もあります。

Intlとは

各言語に依存した日付や数値フォーマットを共通化するための国際化API(Internationalization API)です。

日付のフォーマットにはIntl.DateTimeFormatを利用します。

Intl.DateTimeFormat

基本的な使い方

ロケールと各項目の書式を指定してフォーマットします。

const options = {
  month: 'short',
  day: 'numeric',
  weekday: 'short',
};

new Intl.DateTimeFormat('ja-JP', options).format(new Date('2020-01-01'));
// > "1月1日(水)"

new Intl.DateTimeFormat('en-US', options).format(new Date('2020-01-01'));
// >> "Wed, Jan 1"

moment.jsのように日付の表記順などの細かい指定はできませんが、ロケールごとの書式指定が不要になるという点ではメリットがあります。

optionsの指定による表記一覧

何を指定するとどう表記されるか明示されているドキュメントが見当たらなかったので、一覧を出してみました。

例えばja-JPの場合monthlong/short/narrowですべて同じ表記になりますがen-USの場合は表記が異なります。
指定方法によっては結局ロケールごとの書式指定が必要になってしまいます。

year, month, day, weekdayの表記一覧(Chrome)
options ja-JP en-US
{ year: 'numeric' } 2020年 2020
{ year: '2-digit' } 20年 20
{ month: 'numeric' } 1月 1
{ month: '2-digit' } 01月 01
{ month: 'long' } 1月 January
{ month: 'short' } 1月 Jan
{ month: 'narrow' } 1月 J
{ day: 'numeric' } 1日 1
{ day: '2-digit' } 01日 01
{ weekday: 'long' } 水曜日 Wednesday
{ weekday: 'short' } Wed
{ weekday: 'narrow' } W
{ year: 'numeric', month: 'numeric' } 2020/1 1/2020
{ year: 'numeric', month: '2-digit' } 2020/01 01/2020
{ year: 'numeric', month: 'long' } 2020年1月 January 2020
{ year: 'numeric', month: 'short' } 2020年1月 Jan 2020
{ year: 'numeric', month: 'narrow' } 2020年1月 J 2020
{ year: '2-digit', month: 'numeric' } 20/1 1/20
{ year: '2-digit', month: '2-digit' } 20/01 01/20
{ year: '2-digit', month: 'long' } 20年1月 January 20
{ year: '2-digit', month: 'short' } 20年1月 Jan 20
{ year: '2-digit', month: 'narrow' } 20年1月 J 20
{ month: 'numeric', day: 'numeric' } 1/1 1/1
{ month: 'numeric', day: '2-digit' } 1/01 1/01
{ month: '2-digit', day: 'numeric' } 01/1 01/1
{ month: '2-digit', day: '2-digit' } 01/01 01/01
{ month: 'long', day: 'numeric' } 1月1日 January 1
{ month: 'long', day: '2-digit' } 1月01日 January 01
{ month: 'short', day: 'numeric' } 1月1日 Jan 1
{ month: 'short', day: '2-digit' } 1月01日 Jan 01
{ month: 'narrow', day: 'numeric' } 1月1日 J 1
{ month: 'narrow', day: '2-digit' } 1月01日 J 01
{ day: 'numeric', weekday: 'long' } 1日水曜日 1 Wednesday
{ day: 'numeric', weekday: 'short' } 1日(水) 1 Wed
{ day: 'numeric', weekday: 'narrow' } 1日(水) 1 W
{ day: '2-digit', weekday: 'long' } 01日水曜日 01 Wednesday
{ day: '2-digit', weekday: 'short' } 01日(水) 01 Wed
{ day: '2-digit', weekday: 'narrow' } 01日(水) 01 W
{ year: 'numeric', month: 'numeric', day: 'numeric' } 2020/1/1 1/1/2020
{ year: 'numeric', month: 'numeric', day: '2-digit' } 2020/1/01 1/01/2020
{ year: 'numeric', month: '2-digit', day: 'numeric' } 2020/01/1 01/1/2020
{ year: 'numeric', month: '2-digit', day: '2-digit' } 2020/01/01 01/01/2020
{ year: 'numeric', month: 'long', day: 'numeric' } 2020年1月1日 January 1, 2020
{ year: 'numeric', month: 'long', day: '2-digit' } 2020年1月01日 January 01, 2020
{ year: 'numeric', month: 'short', day: 'numeric' } 2020年1月1日 Jan 1, 2020
{ year: 'numeric', month: 'short', day: '2-digit' } 2020年1月01日 Jan 01, 2020
{ year: 'numeric', month: 'narrow', day: 'numeric' } 2020年1月1日 J 1, 2020
{ year: 'numeric', month: 'narrow', day: '2-digit' } 2020年1月01日 J 01, 2020
{ year: '2-digit', month: 'numeric', day: 'numeric' } 20/1/1 1/1/20
{ year: '2-digit', month: 'numeric', day: '2-digit' } 20/1/01 1/01/20
{ year: '2-digit', month: '2-digit', day: 'numeric' } 20/01/1 01/1/20
{ year: '2-digit', month: '2-digit', day: '2-digit' } 20/01/01 01/01/20
{ year: '2-digit', month: 'long', day: 'numeric' } 20年1月1日 January 1, 20
{ year: '2-digit', month: 'long', day: '2-digit' } 20年1月01日 January 01, 20
{ year: '2-digit', month: 'short', day: 'numeric' } 20年1月1日 Jan 1, 20
{ year: '2-digit', month: 'short', day: '2-digit' } 20年1月01日 Jan 01, 20
{ year: '2-digit', month: 'narrow', day: 'numeric' } 20年1月1日 J 1, 20
{ year: '2-digit', month: 'narrow', day: '2-digit' } 20年1月01日 J 01, 20
{ month: 'numeric', day: 'numeric', weekday: 'long' } 1/1水曜日 Wednesday, 1/1
{ month: 'numeric', day: 'numeric', weekday: 'short' } 1/1(水) Wed, 1/1
{ month: 'numeric', day: 'numeric', weekday: 'narrow' } 1/1(水) W, 1/1
{ month: 'numeric', day: '2-digit', weekday: 'long' } 1/01水曜日 Wednesday, 1/01
{ month: 'numeric', day: '2-digit', weekday: 'short' } 1/01(水) Wed, 1/01
{ month: 'numeric', day: '2-digit', weekday: 'narrow' } 1/01(水) W, 1/01
{ month: '2-digit', day: 'numeric', weekday: 'long' } 01/1水曜日 Wednesday, 01/1
{ month: '2-digit', day: 'numeric', weekday: 'short' } 01/1(水) Wed, 01/1
{ month: '2-digit', day: 'numeric', weekday: 'narrow' } 01/1(水) W, 01/1
{ month: '2-digit', day: '2-digit', weekday: 'long' } 01/01水曜日 Wednesday, 01/01
{ month: '2-digit', day: '2-digit', weekday: 'short' } 01/01(水) Wed, 01/01
{ month: '2-digit', day: '2-digit', weekday: 'narrow' } 01/01(水) W, 01/01
{ month: 'long', day: 'numeric', weekday: 'long' } 1月1日水曜日 Wednesday, January 1
{ month: 'long', day: 'numeric', weekday: 'short' } 1月1日(水) Wed, January 1
{ month: 'long', day: 'numeric', weekday: 'narrow' } 1月1日(水) W, January 1
{ month: 'long', day: '2-digit', weekday: 'long' } 1月01日水曜日 Wednesday, January 01
{ month: 'long', day: '2-digit', weekday: 'short' } 1月01日(水) Wed, January 01
{ month: 'long', day: '2-digit', weekday: 'narrow' } 1月01日(水) W, January 01
{ month: 'short', day: 'numeric', weekday: 'long' } 1月1日水曜日 Wednesday, Jan 1
{ month: 'short', day: 'numeric', weekday: 'short' } 1月1日(水) Wed, Jan 1
{ month: 'short', day: 'numeric', weekday: 'narrow' } 1月1日(水) W, Jan 1
{ month: 'short', day: '2-digit', weekday: 'long' } 1月01日水曜日 Wednesday, Jan 01
{ month: 'short', day: '2-digit', weekday: 'short' } 1月01日(水) Wed, Jan 01
{ month: 'short', day: '2-digit', weekday: 'narrow' } 1月01日(水) W, Jan 01
{ month: 'narrow', day: 'numeric', weekday: 'long' } 1月1日水曜日 Wednesday, J 1
{ month: 'narrow', day: 'numeric', weekday: 'short' } 1月1日(水) Wed, J 1
{ month: 'narrow', day: 'numeric', weekday: 'narrow' } 1月1日(水) W, J 1
{ month: 'narrow', day: '2-digit', weekday: 'long' } 1月01日水曜日 Wednesday, J 01
{ month: 'narrow', day: '2-digit', weekday: 'short' } 1月01日(水) Wed, J 01
{ month: 'narrow', day: '2-digit', weekday: 'narrow' } 1月01日(水) W, J 01
{ year: 'numeric', month: 'numeric', day: 'numeric', weekday: 'long' } 2020/1/1水曜日 Wednesday, 1/1/2020
{ year: 'numeric', month: 'numeric', day: 'numeric', weekday: 'short' } 2020/1/1(水) Wed, 1/1/2020
{ year: 'numeric', month: 'numeric', day: 'numeric', weekday: 'narrow' } 2020/1/1(水) W, 1/1/2020
{ year: 'numeric', month: 'numeric', day: '2-digit', weekday: 'long' } 2020/1/01水曜日 Wednesday, 1/01/2020
{ year: 'numeric', month: 'numeric', day: '2-digit', weekday: 'short' } 2020/1/01(水) Wed, 1/01/2020
{ year: 'numeric', month: 'numeric', day: '2-digit', weekday: 'narrow' } 2020/1/01(水) W, 1/01/2020
{ year: 'numeric', month: '2-digit', day: 'numeric', weekday: 'long' } 2020/01/1水曜日 Wednesday, 01/1/2020
{ year: 'numeric', month: '2-digit', day: 'numeric', weekday: 'short' } 2020/01/1(水) Wed, 01/1/2020
{ year: 'numeric', month: '2-digit', day: 'numeric', weekday: 'narrow' } 2020/01/1(水) W, 01/1/2020
{ year: 'numeric', month: '2-digit', day: '2-digit', weekday: 'long' } 2020/01/01水曜日 Wednesday, 01/01/2020
{ year: 'numeric', month: '2-digit', day: '2-digit', weekday: 'short' } 2020/01/01(水) Wed, 01/01/2020
{ year: 'numeric', month: '2-digit', day: '2-digit', weekday: 'narrow' } 2020/01/01(水) W, 01/01/2020
{ year: 'numeric', month: 'long', day: 'numeric', weekday: 'long' } 2020年1月1日水曜日 Wednesday, January 1, 2020
{ year: 'numeric', month: 'long', day: 'numeric', weekday: 'short' } 2020年1月1日(水) Wed, January 1, 2020
{ year: 'numeric', month: 'long', day: 'numeric', weekday: 'narrow' } 2020年1月1日(水) W, January 1, 2020
{ year: 'numeric', month: 'long', day: '2-digit', weekday: 'long' } 2020年1月01日水曜日 Wednesday, January 01, 2020
{ year: 'numeric', month: 'long', day: '2-digit', weekday: 'short' } 2020年1月01日(水) Wed, January 01, 2020
{ year: 'numeric', month: 'long', day: '2-digit', weekday: 'narrow' } 2020年1月01日(水) W, January 01, 2020
{ year: 'numeric', month: 'short', day: 'numeric', weekday: 'long' } 2020年1月1日水曜日 Wednesday, Jan 1, 2020
{ year: 'numeric', month: 'short', day: 'numeric', weekday: 'short' } 2020年1月1日(水) Wed, Jan 1, 2020
{ year: 'numeric', month: 'short', day: 'numeric', weekday: 'narrow' } 2020年1月1日(水) W, Jan 1, 2020
{ year: 'numeric', month: 'short', day: '2-digit', weekday: 'long' } 2020年1月01日水曜日 Wednesday, Jan 01, 2020
{ year: 'numeric', month: 'short', day: '2-digit', weekday: 'short' } 2020年1月01日(水) Wed, Jan 01, 2020
{ year: 'numeric', month: 'short', day: '2-digit', weekday: 'narrow' } 2020年1月01日(水) W, Jan 01, 2020
{ year: 'numeric', month: 'narrow', day: 'numeric', weekday: 'long' } 2020年1月1日水曜日 Wednesday, J 1, 2020
{ year: 'numeric', month: 'narrow', day: 'numeric', weekday: 'short' } 2020年1月1日(水) Wed, J 1, 2020
{ year: 'numeric', month: 'narrow', day: 'numeric', weekday: 'narrow' } 2020年1月1日(水) W, J 1, 2020
{ year: 'numeric', month: 'narrow', day: '2-digit', weekday: 'long' } 2020年1月01日水曜日 Wednesday, J 01, 2020
{ year: 'numeric', month: 'narrow', day: '2-digit', weekday: 'short' } 2020年1月01日(水) Wed, J 01, 2020
{ year: 'numeric', month: 'narrow', day: '2-digit', weekday: 'narrow' } 2020年1月01日(水) W, J 01, 2020
{ year: '2-digit', month: 'numeric', day: 'numeric', weekday: 'long' } 20/1/1水曜日 Wednesday, 1/1/20
{ year: '2-digit', month: 'numeric', day: 'numeric', weekday: 'short' } 20/1/1(水) Wed, 1/1/20
{ year: '2-digit', month: 'numeric', day: 'numeric', weekday: 'narrow' } 20/1/1(水) W, 1/1/20
{ year: '2-digit', month: 'numeric', day: '2-digit', weekday: 'long' } 20/1/01水曜日 Wednesday, 1/01/20
{ year: '2-digit', month: 'numeric', day: '2-digit', weekday: 'short' } 20/1/01(水) Wed, 1/01/20
{ year: '2-digit', month: 'numeric', day: '2-digit', weekday: 'narrow' } 20/1/01(水) W, 1/01/20
{ year: '2-digit', month: '2-digit', day: 'numeric', weekday: 'long' } 20/01/1水曜日 Wednesday, 01/1/20
{ year: '2-digit', month: '2-digit', day: 'numeric', weekday: 'short' } 20/01/1(水) Wed, 01/1/20
{ year: '2-digit', month: '2-digit', day: 'numeric', weekday: 'narrow' } 20/01/1(水) W, 01/1/20
{ year: '2-digit', month: '2-digit', day: '2-digit', weekday: 'long' } 20/01/01水曜日 Wednesday, 01/01/20
{ year: '2-digit', month: '2-digit', day: '2-digit', weekday: 'short' } 20/01/01(水) Wed, 01/01/20
{ year: '2-digit', month: '2-digit', day: '2-digit', weekday: 'narrow' } 20/01/01(水) W, 01/01/20
{ year: '2-digit', month: 'long', day: 'numeric', weekday: 'long' } 20年1月1日水曜日 Wednesday, January 1, 20
{ year: '2-digit', month: 'long', day: 'numeric', weekday: 'short' } 20年1月1日(水) Wed, January 1, 20
{ year: '2-digit', month: 'long', day: 'numeric', weekday: 'narrow' } 20年1月1日(水) W, January 1, 20
{ year: '2-digit', month: 'long', day: '2-digit', weekday: 'long' } 20年1月01日水曜日 Wednesday, January 01, 20
{ year: '2-digit', month: 'long', day: '2-digit', weekday: 'short' } 20年1月01日(水) Wed, January 01, 20
{ year: '2-digit', month: 'long', day: '2-digit', weekday: 'narrow' } 20年1月01日(水) W, January 01, 20
{ year: '2-digit', month: 'short', day: 'numeric', weekday: 'long' } 20年1月1日水曜日 Wednesday, Jan 1, 20
{ year: '2-digit', month: 'short', day: 'numeric', weekday: 'short' } 20年1月1日(水) Wed, Jan 1, 20
{ year: '2-digit', month: 'short', day: 'numeric', weekday: 'narrow' } 20年1月1日(水) W, Jan 1, 20
{ year: '2-digit', month: 'short', day: '2-digit', weekday: 'long' } 20年1月01日水曜日 Wednesday, Jan 01, 20
{ year: '2-digit', month: 'short', day: '2-digit', weekday: 'short' } 20年1月01日(水) Wed, Jan 01, 20
{ year: '2-digit', month: 'short', day: '2-digit', weekday: 'narrow' } 20年1月01日(水) W, Jan 01, 20
{ year: '2-digit', month: 'narrow', day: 'numeric', weekday: 'long' } 20年1月1日水曜日 Wednesday, J 1, 20
{ year: '2-digit', month: 'narrow', day: 'numeric', weekday: 'short' } 20年1月1日(水) Wed, J 1, 20
{ year: '2-digit', month: 'narrow', day: 'numeric', weekday: 'narrow' } 20年1月1日(水) W, J 1, 20
{ year: '2-digit', month: 'narrow', day: '2-digit', weekday: 'long' } 20年1月01日水曜日 Wednesday, J 01, 20
{ year: '2-digit', month: 'narrow', day: '2-digit', weekday: 'short' } 20年1月01日(水) Wed, J 01, 20
{ year: '2-digit', month: 'narrow', day: '2-digit', weekday: 'narrow' } 20年1月01日(水) W, J 01, 20

ブラウザによる差異

各ブラウザごとの実装に差異があり、指定したoptionによっては表記が異なる場合があります。

const options = {
  month: 'long',
  day: 'numeric',
  weekday: 'long',
};

new Intl.DateTimeFormat('ja-JP', options).format(new Date('2020-01-01'));
// Chrome, Firefox > "1月1日水曜日"
// Safari > "1月1日 水曜日" 

まとめ

自由な書式を定義したい場合はmoment.jsなどのライブラリを利用した方が良いかもしれませんが、標準的な書式で十分なのであればIntl.DateTimeFormatを利用するのもありかと思います。

書式の細かい指定ができないため出力してみないと分からない、ブラウザにより表記が異なるケースがある、という点には注意が必要です。

10
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?