JavaScriptにおいて、日付のフォーマット処理は長年多くの開発者を悩ませてきた課題の一つです。
かつてのJavaScriptでは、標準のDateオブジェクトが持つ機能が限定的であったため、日付を「YYYY/MM/DD」のような形式に変換するだけでも煩雑なコードを書く必要がありました。
しかし、現在のJavaScript(2026年時点)では、標準APIの進化や強力なライブラリの登場により、日付操作の柔軟性は飛躍的に向上しています。
特に多言語対応(国際化)が求められる現代のWeb開発において、標準のIntl.DateTimeFormatを使いこなすことは必須のスキルと言えるでしょう。
本記事では、初心者からプロフェッショナルまで活用できる、JavaScriptの日付フォーマット手法について詳しく解説します。
従来のDateオブジェクトによるフォーマットの問題点
JavaScriptの基本であるDateオブジェクトは、1995年の登場以来、日付操作の根幹を担ってきました。
しかし、Dateオブジェクトには「フォーマット用のメソッド」がほとんど用意されていません。
例えば「2026年05月01日」という文字列を取得したい場合、年・月・日を個別に取得して結合する処理が必要です。
// 従来の面倒な書き方
const now = new Date();
const year = now.getFullYear();
const month = String(now.getMonth() + 1).padStart(2, '0'); // 月は0から始まるため+1が必要
const day = String(now.getDate()).padStart(2, '0');
const formattedDate = `${year}/${month}/${day}`;
console.log(formattedDate);
2026/05/01
このように、「月」のインデックスが0から始まる仕様や、2桁表示にするためのpadStart処理など、直感的ではない実装が多く含まれます。
こうした冗長なコードは、バグの原因になりやすく、保守性の低下を招きます。
そのため、現在は次に紹介する標準APIやライブラリを利用する方法が主流となっています。
標準API「Intl.DateTimeFormat」による高度なフォーマット
モダンなJavaScript開発において、最も推奨されるのがIntl.DateTimeFormatオブジェクトの利用です。
これはECMAScript国際化APIの一部であり、ユーザーの言語や地域に合わせた最適な表示を簡単に実現できます。
基本的な使い方
Intl.DateTimeFormatを使用すると、各国の慣習に基づいた日付形式を1行で取得できます。
const date = new Date(2026, 4, 1); // 2026年5月1日
// 日本語(日本)のフォーマット
const formatterJP = new Intl.DateTimeFormat('ja-JP');
console.log(formatterJP.format(date));
// 英語(アメリカ)のフォーマット
const formatterUS = new Intl.DateTimeFormat('en-US');
console.log(formatterUS.format(date));
2026/05/01
5/1/2026
このように、コンストラクタにロケール(’ja-JP’など)を渡すだけで、その地域で一般的な区切り文字や並び順が適用されます。
詳細なオプション設定
さらに第2引数にオブジェクトを渡すことで、年・月・日・曜日の表示スタイルを細かくカスタマイズ可能です。
const date = new Date(2026, 4, 1, 14, 30);
const options = {
year: 'numeric', // 2026
month: 'long', // 5月(ロケールにより変化)
day: 'numeric', // 1
weekday: 'long', // 金曜日
hour: '2-digit', // 14
minute: '2-digit', // 30
hour12: false // 24時間表記
};
const formatter = new Intl.DateTimeFormat('ja-JP', options);
console.log(formatter.format(date));
2026年5月1日金曜日 14:30
month: 'short'やmonth: '2-digit'など、指定する値によって「5月」「5」「05」といった切り替えが容易に行えます。
外部ライブラリを使わずにこれほど詳細な設定ができる点は、パフォーマンスの観点からも大きなメリットです。
次世代の標準:Temporal APIの活用
2026年現在、JavaScriptの新しい日付標準として注目されているのがTemporal APIです。
従来のDateオブジェクトが抱えていた「ミュータブル(不変ではない)」という問題や、タイムゾーン処理の複雑さを根本から解決するために導入されました。
Temporalによる直感的なフォーマット
Temporal.Now.plainDateISO()などを使用して、現在の日付を直接取得し、そのままフォーマットに渡すことができます。
// Temporalのプレインな日付オブジェクト(タイムゾーンなし)
const date = Temporal.PlainDate.from({ year: 2026, month: 5, day: 1 });
// Intl.DateTimeFormatとの連携もスムーズ
console.log(date.toLocaleString('ja-JP'));
2026/5/1
Temporal APIの最大の特徴は、「月」が1から始まる1ベースのカウントであることです。
これにより、開発者が「+1」をする手間がなくなり、コードの可読性が格段に向上しました。
また、不変(Immutable)なオブジェクトであるため、フォーマットの過程で元の値が書き換わってしまう心配もありません。
サードパーティライブラリによる効率化
標準APIが進化してもなお、特定の書式(例:YYYY-MM-DD HH:mm:ss)を文字列で指定したい場合には、ライブラリの利用が非常に便利です。
ここでは、現代の主流となっている2つのライブラリを紹介します。
Day.js:軽量で直感的な操作
Day.jsは、かつて主流だったMoment.jsと互換性のあるAPIを持ちながら、極めて軽量なライブラリです。
import dayjs from 'dayjs';
const now = dayjs('2026-05-01');
console.log(now.format('YYYY年MM月DD日 HH:mm:ss'));
2026年05月01日 00:00:00
format()メソッドに任意の文字列を渡すだけで、思い通りの形に出力できるのが最大の魅力です。
また、プラグインを導入することで、相対時間(「3日前」など)の表示も簡単に行えます。
date-fns:関数型の利便性
date-fnsは、各機能が独立した関数として提供されているライブラリです。
Tree-shakingが効きやすいため、必要な機能だけをバンドルでき、ビルドサイズを最小限に抑えられます。
import { format } from 'date-fns';
import { ja } from 'date-fns/locale';
const date = new Date(2026, 4, 1);
const result = format(date, 'yyyy年MMMMdo (eeee)', { locale: ja });
console.log(result);
2026年5月1日 (金曜日)
関数型プログラミングを好む開発者や、プロジェクトの軽量化を最優先する現場で強く支持されています。
日付フォーマット手法の比較表
プロジェクトに最適な手法を選ぶための比較を以下の表にまとめました。
| 手法 | メリット | デメリット | 推奨される用途 |
|---|---|---|---|
| Dateオブジェクト | 追加学習・導入コストがゼロ | コードが冗長、月が0開始 | 非常に小規模なスクリプト |
| Intl API | 標準搭載、多言語対応が容易 | 自由な文字列指定が難しい | BtoCの多言語対応サイト |
| Temporal API | 最新標準、直感的で高機能 | 古い環境ではポリフィルが必要 | モダンな新規プロジェクト |
| Day.js / date-fns | 書式指定が自由自在 | ライブラリの読み込みが必要 | 複雑な日付操作・表示が必要なアプリ |
パフォーマンスと最適化のポイント
日付のフォーマット処理は、一見すると負荷が低いように思えますが、大量のデータを一覧表示する際には注意が必要です。
特にIntl.DateTimeFormatを使用する場合、ループの中で毎回インスタンスを作成するのは避けましょう。
// パフォーマンスが悪い例
data.forEach(item => {
const formatter = new Intl.DateTimeFormat('ja-JP'); // 毎回作成
console.log(formatter.format(item.date));
});
// パフォーマンスが良い例
const formatter = new Intl.DateTimeFormat('ja-JP'); // 一度だけ作成
data.forEach(item => {
console.log(formatter.format(item.date));
});
インスタンスを再利用することで、初期化コストを大幅に削減でき、スムーズなユーザー体験を提供できます。
また、ライブラリを使用する場合は、プロジェクトの規模に応じてDay.jsかdate-fnsかを慎重に選択し、不要な機能をバンドルしないように心がけてください。
まとめ
JavaScriptでの日付フォーマットは、かつての煩雑な時代を脱し、強力な標準機能と洗練されたライブラリによって整理されました。
基本的にはIntl.DateTimeFormatを第一の選択肢とし、ブラウザの標準機能を最大限に活用することをおすすめします。
もし「YYYY-MM-DD」のような特定の文字列形式への変換が頻発したり、複雑な日付計算が必要な場合は、Day.jsやdate-fnsといったライブラリを適宜組み合わせるのがベストプラクティスです。
また、2026年以降のモダンな開発においては、次世代の標準であるTemporal APIの採用も積極的に検討していくべきでしょう。
各手法のメリットとデメリットを正しく理解し、プロジェクトの要件やターゲットブラウザに合わせて最適な日付フォーマット手法を選択してください。
