【JavaScript】日付・時刻フォーマットのベストプラクティスまとめ
JavaScript で日付や時刻を任意の形式で表示したい、タイムゾーンを指定してフォーマットしたい、といったケースは非常に多いです。
この記事では、JSで使える日付フォーマット方法の代表的な手法をまとめつつ、どの場面で何を使うべきかを整理しました。
実務で迷わないためのメリット・デメリットや具体例も付けています。
Next.js/Node.js/フロントエンドアプリで日付を扱う方の備忘録として活用できれば幸いです
Intl.DateTimeFormat:一番モダンで信頼性の高いフォーマット
Intl.DateTimeFormatは 国際化API(Internationalization API)の一つで、最も推奨される日付フォーマット手段です。
特徴
- タイムゾーンの指定が可能
- 多言語に強い
- ライブラリ不要(標準機能)
- ブラウザ/Node.jsどちらでも安定
const date = new Date(Date.UTC(2023, 5, 16, 3, 23, 16, 738));
const formatted = new Intl.DateTimeFormat("ja-JP", {
timeZone: "Asia/Tokyo",
year: "numeric",
month: "2-digit",
day: "2-digit"
}).format(date);
console.log(formatted);
// => '2023/06/16'
注意点:ICUのDate/Time Format Syntaxとは直接互換ではない
ICUのYYYYやdd-MMのような記法はそのまま使えません。
フォーマットは必ずオプションオブジェクトで指定します。
ICU syntax の詳細はこちら
toISOString:UTC固定のISO 8601を返す(API返却などに最適)
toISOString()は最もシンプルに ISO8601 文字列を生成できます。
new Date().toISOString();
// → '2023-05-16T04:26:15.942Z'
特徴
- 返却される値は常にUTC(Z表記)
- タイムゾーンの変更不可
- REST API、DB保存などに最適
toLocaleDateString/toLocaleTimeString:簡易フォーマットに便利
toLocaleDateStringとtoLocaleTimeStringは ローカル依存のフォーマットを作るのに便利です。[1]
const date = new Date();
const dateString = `${date.toLocaleDateString("ja-JP", { timeZone: "Asia/Tokyo" })} ${date.toLocaleTimeString("ja-JP", { timeZone: "Asia/Tokyo" })}`
console.log(dateString);
// → '2023/5/16 13:47:53'
特徴
- 言語・地域の形式に合わせて自動で整形
- タイムゾーン指定が可能
注意点
- ロケールごとの挙動に揺れがある
- カスタム性は Intl.DateTimeFormat より弱い
toLocaleString:日時まとめてフォーマットしたい場合に便利
toLocaleString()は「日付+時刻」をまとめてロケール形式で返します。
カスタマイズするならIntl.DateTimeFormatの.format()と同じくオプションを渡せばOK。
new Date().toLocaleString("ja-JP", {
timeZone: "Asia/Tokyo",
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
second: "2-digit"
});
// 例 → "2023/05/16 13:47:53"
【実務でよく使う】任意フォーマット(YYYY-MM-DD HH:mm:ss)を作る方法
JavaScript標準APIは「任意のフォーマット記述(YYYY-MM-DD)を直接書けない」という欠点があります。
そのため、実務では以下の方法が一般的です。
1. Intl.DateTimeFormatのformatToPartsで自前組み立て
これが標準機能だけで自由なフォーマットを作る最も実践的な方法です。
const date = new Date();
const parts = new Intl.DateTimeFormat("ja-JP", {
timeZone: "Asia/Tokyo",
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
second: "2-digit"
}).formatToParts(date);
const dict = Object.fromEntries(parts.map(p => [p.type, p.value]));
const result = `${dict.year}-${dict.month}-${dict.day} ${dict.hour}:${dict.minute}:${dict.second}`;
console.log(result);
// → "2023-05-16 13:47:53"
2. Dateメソッドを使ってシンプルに手動で整形(標準APIだけ)
const d = new Date();
const pad = n => String(n).padStart(2, "0");
const result = `${d.getFullYear()}-${pad(d.getMonth()+1)}-${pad(d.getDate())} `
+ `${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;
console.log(result);
こちらは軽量で速いですが、タイムゾーン変更にはDateの補正処理が必要です。
まとめ
| 利用シーン | ベストな方法 |
|---|---|
| タイムゾーン指定したい | Intl.DateTimeFormat |
| API の返却形式 | toISOString (UTC) |
| ロケールごとの自動整形 | toLocaleDateString / toLocaleTimeString |
| 任意のフォーマット(YYYY-MM-DD など) | Intl.formatToParts またはライブラリの使用 |
| パフォーマンス重視の軽量フォーマット | 手動で組み立て |
参考
標準機能でDateをformatする色々(toLocaleString/Intl.DateTimeFormat/etc)
Intl.DateTimeFormat を使うときは気をつけないと50倍くらい遅くなるしメモリももりもり食う
-
toLocaleDateStringは、Dateオブジェクトの「日付」部を表す言語に依存した文字列を、toLocaleTimeStringは、日付の時間部分を言語に依存して表現した文字列を返します。 ↩︎
Discussion