日付と時刻の操作 — Dateの生成・フォーマット・差分計算と月0始まりの罠
「投稿日時を表示する」「予約の何日前か計算する」「今日の日付でファイル名を作る」——日付の処理はほぼすべてのアプリで登場します。Date は便利な反面、月が0から始まるなどの独特な落とし穴があり、初心者がつまずく定番分野でもあります。
この章では、Date の生成から各要素の取り出し、表示用のフォーマット、差分・加算の計算、そしてタイムゾーンの注意点までを、引数つきの表で逆引きできるように整理します。
Date オブジェクトとは — 現在時刻の取得
Date は「ある一点の日時」を表す組み込みオブジェクトです。内部的には1970年1月1日(UTC)からの経過ミリ秒という1つの数値で時刻を保持しています。
const now = new Date(); // 現在の日時
console.log(now); // 例: 2026-06-06T...(実行した瞬間の日時)
Date.now(); // 例: 1781049600000(現在のミリ秒。数値だけが欲しいとき)
Date の作り方 — 引数で挙動が変わる
new Date() は渡す引数によって意味が変わります。ここが最初の関門です。
構文: new Date(...)
| 渡し方 | 引数 | 生成される日時 |
|---|---|---|
new Date() | なし | 現在の日時 |
new Date(ms) | ms:1970年からのミリ秒 | そのミリ秒に対応する日時 |
new Date(dateString) | dateString:日付文字列 | 文字列を解釈した日時('2026-06-06' など) |
new Date(year, monthIndex, day, ...) | 年・月(0始まり)・日・時・分・秒 | 各要素を指定した日時 |
new Date(0); // 1970-01-01T00:00:00.000Z(基準点)
new Date('2026-06-06'); // ISO形式の文字列から
new Date(2026, 5, 6); // 2026年6月6日(※月は 5 で6月!)
学習者new Date(2026, 5, 6) が6月…?5 を渡したのに6月になるの、絶対バグらせる自信ある…。
最大の罠 — 月は「0始まり」
Date の月は 0〜11で表されます。0が1月、11が12月です。日(day)や年は通常どおりなのに、月だけ0始まりという非対称さが混乱の元です。
const d = new Date(2026, 0, 1); // 2026年1月1日(0 = 1月)
const d2 = new Date(2026, 11, 31); // 2026年12月31日(11 = 12月)日付の各要素を取り出す
生成した Date から年・月・日などを取り出すメソッド群です。いずれも引数なしで、数値を返します。
| メソッド | 戻り値 |
|---|---|
date.getFullYear() | 年(4桁。getYear() は使わない) |
date.getMonth() | 月(0〜11。表示時は +1) |
date.getDate() | 日(1〜31) |
date.getDay() | 曜日(0=日曜 〜 6=土曜) |
date.getHours() | 時(0〜23) |
date.getMinutes() | 分(0〜59) |
date.getSeconds() | 秒(0〜59) |
date.getTime() | 1970年からのミリ秒(差分計算に使う) |
const d = new Date(2026, 5, 6, 14, 30); // 2026-06-06 14:30
d.getFullYear(); // 2026
d.getMonth() + 1; // 6(+1して人間が読む月に)
d.getDate(); // 6
d.getHours(); // 14
先生getDay()(曜日)と getDate()(日にち)は名前が紛らわしいから要注意。「Dayは曜日、Dateは日にち」とセットで覚えよう。
フォーマット — 表示用の文字列にする
日本語の「2026年6月6日」や「6/6 14:30」のような表示は、要素を1つずつ組み立てなくても専用メソッドで作れます。
ロケールに合わせて整形 — toLocaleString 系
構文: date.toLocaleDateString(locales?, options?)
| 引数 | 説明 |
|---|---|
locales(省略可) | 言語・地域('ja-JP' など)。省略すると実行環境の設定 |
options(省略可) | 表示形式({ year: 'numeric', month: 'long', day: 'numeric' } など) |
戻り値: その地域の慣習で整形した文字列
const d = new Date(2026, 5, 6, 14, 30);
d.toLocaleDateString('ja-JP'); // "2026/6/6"
d.toLocaleString('ja-JP'); // "2026/6/6 14:30:00"(日付+時刻)
d.toLocaleDateString('ja-JP', {
year: 'numeric',
month: 'long',
day: 'numeric',
weekday: 'long',
}); // "2026年6月6日土曜日"機械可読な形式 — toISOString
構文: date.toISOString()(引数なし)
戻り値: "2026-06-06T05:30:00.000Z" のようなISO 8601形式の文字列(UTC)
new Date(2026, 5, 6).toISOString(); // "2026-06-05T15:00:00.000Z"日付の計算 — 差分と加算
差分(何日・何時間離れているか)
getTime() でミリ秒に変換し、引き算してから単位を割り戻します。
const start = new Date(2026, 5, 1);
const end = new Date(2026, 5, 6);
const diffMs = end.getTime() - start.getTime(); // ミリ秒の差
const diffDays = diffMs / (1000 * 60 * 60 * 24); // 5(日数に変換)
学習者1000 * 60 * 60 * 24 って何の数字…?毎回これ書くの大変そう。
これは「1日 = 1000ミリ秒 × 60秒 × 60分 × 24時間」を表す定数です。前章の数値の扱いで見たとおり、Date の正体はミリ秒という数値なので、引き算が日数計算になります。頻繁に書くなら定数化するか、後述のライブラリに任せます。
加算(◯日後・◯時間後)
setDate() などのセッターで日付を進められます。setDate(getDate() + 7) のように現在値に足すのが基本です。月をまたぐ繰り上がりも自動でやってくれます。
const d = new Date(2026, 5, 6);
d.setDate(d.getDate() + 7); // 7日後(6/13)
// 6/28 に +7 すれば自動で 7/5 になる(月またぎも処理される)タイムゾーンの注意点
Date は「内部はUTC(協定世界時)の絶対時刻、表示や getHours() などはローカルタイムゾーン」という二面性を持ちます。
toISOString()の末尾Zは UTC を意味するgetHours()などのゲッターは実行環境のローカル時刻を返す- 日付だけの文字列
'2026-06-06'は UTCの0時として解釈され、日本(+9時間)で表示すると意図とずれることがある
// 環境のタイムゾーンによって結果が変わりうる
new Date('2026-06-06').getDate(); // 日本だと 6 になるとは限らないサーバーとブラウザでタイムゾーンが異なる、夏時間がある、といった条件が絡むと一気に複雑になります。時刻の厳密さが必要なシステムでは、UTCで保存し表示時に変換するのが基本方針です。
これからの選択肢 — Temporal とライブラリ
早見表
| やりたいこと | 使うもの |
|---|---|
| 現在日時 | new Date() / Date.now()(ミリ秒) |
| 年・日を取得 | getFullYear() / getDate() |
| 月を取得(人間向け) | getMonth() + 1 |
| 曜日を取得 | getDay()(0=日〜6=土) |
| 「2026年6月6日」表示 | toLocaleDateString('ja-JP', {...}) |
| 保存・送信用の文字列 | toISOString() |
| 日数の差分 | (d2 - d1) / (1000*60*60*24) |
| ◯日後 | d.setDate(d.getDate() + n)(破壊的) |
よくあるハマりどころ

1. 月が0始まり
最頻出の罠。new Date(2026, 5, 6) は6月。生成時は「実際の月 − 1」、getMonth() の結果は「+1」で人間の月に直します。
2. getDay() と getDate() を取り違える
getDay() は曜日(0〜6)、getDate() は日にち(1〜31)。名前が似ているので逆に使いがちです。
3. セッターが元の日付を壊す
setDate などは破壊的。元の値を残すなら const copy = new Date(original) してから操作します。
4. 文字列のパースは形式依存
new Date('2026/06/06') や new Date('June 6, 2026') は環境によって解釈が異なることがあります。'2026-06-06' のISO形式が最も安全です。非標準の形式を渡すと Invalid Date になることもあります。
new Date('2026-06-06'); // OK(ISO形式)
new Date('06-06-2026'); // 環境依存。避けるちゃんと使うためのポイント
Dateの正体は「1970年からのミリ秒」という1つの数値。だから差分は引き算で出せる- 月は0始まり(0=1月)。生成は −1、
getMonth()は +1 getDay()=曜日、getDate()=日にち。混同しない- 表示は
toLocaleString系、保存・送信はtoISOString() - セッター(
setDateなど)は破壊的。コピーしてから操作する - タイムゾーンが絡む厳密な処理や複雑な計算は、Day.js / date-fns などのライブラリに任せる
次の章では、JSONの基礎と実践 を扱います。APIとデータをやり取りするとき、Date を JSON.stringify するとどうなるか——という落とし穴もあわせて見ていきます。