JavaScript 逆引き集 | 日付の差分(日数)

JavaScript JavaScript
スポンサーリンク

JavaScriptで日付の差分(日数)を求める基本と実践

「2つの日時の差を“日数”で知りたい」ときは、2つのDateの差(ミリ秒)を1日のミリ秒で割るのが基本です。まず仕組みと丸め方、そしてタイムゾーンや夏時間の落とし穴を押さえましょう。


基本の考え方と式

// d1, d2 は Dateオブジェクト
const days = (d2 - d1) / (1000 * 60 * 60 * 24); // 1日は86,400,000ms
JavaScript
  • 返り値: 小数の「日数」。端数の扱いは目的に応じて round/ceil/floor を使います。
  • 秒→日: Dateの差はミリ秒なので、1日のミリ秒 86,400,000 で割って日へ換算します。
  • 基本姿勢: 「何を日数と見なすか」(経過時間か、暦日差か)を先に決める。

すぐ使えるテンプレート集

経過“日数”を小数で取得(時間差ベース)

const d1 = new Date("2025-12-01T10:00:00+09:00");
const d2 = new Date("2025-12-05T08:00:00+09:00");

const days = (d2 - d1) / (1000 * 60 * 60 * 24);
console.log(days); // 3.9166...(約3.92日)
JavaScript
  • ポイント: 経過時間を正確に日へ換算。端数は小数として残ります。

“差分日数”を整数で取得(丸め方を選ぶ)

const msPerDay = 1000 * 60 * 60 * 24;
const diffDaysRound = Math.round((d2 - d1) / msPerDay); // 四捨五入
const diffDaysFloor = Math.floor((d2 - d1) / msPerDay); // 切り捨て
const diffDaysCeil  = Math.ceil((d2 - d1) / msPerDay);  // 切り上げ
JavaScript
  • ポイント: 欲しい定義に合わせて丸め方を選ぶ(下の「丸めの指針」を参照)。

暦日(カレンダー日)差を安全に計算(UTCで日付丸め)

function calendarDayDiff(d1, d2) {
  // UTCの“その日の0時”へそろえる(DSTやTZの影響を避ける)
  const u1 = Date.UTC(d1.getFullYear(), d1.getMonth(), d1.getDate());
  const u2 = Date.UTC(d2.getFullYear(), d2.getMonth(), d2.getDate());
  return Math.floor((u2 - u1) / (1000 * 60 * 60 * 24));
}

console.log(calendarDayDiff(new Date("2025-12-01"), new Date("2025-12-05"))); // 4
JavaScript
  • ポイント: 暦日差(YYYY-MM-DDどうしの差)ならUTCで日境界をそろえるのが安全。

“今日を含めて”の残り日数(包括的カウント)

function inclusiveDaysUntil(target) {
  const today = new Date();
  const diff = calendarDayDiff(today, target);
  return diff >= 0 ? diff + 1 : diff; // 未来なら“今日を含めて”+1
}

console.log(inclusiveDaysUntil(new Date("2025-12-10"))); // 例: 今日が5日なら 6
JavaScript
  • ポイント: “含む/含まない”のルールを明示して足し引きする。

平日(営業日)だけ数えたい(簡易・週末除外)

function businessDays(d1, d2) {
  let days = calendarDayDiff(d1, d2);
  let count = 0;
  for (let i = 0; i <= days; i++) {
    const d = new Date(d1.getFullYear(), d1.getMonth(), d1.getDate() + i);
    const w = d.getDay(); // 0:日, 6:土
    if (w !== 0 && w !== 6) count++;
  }
  return count;
}

console.log(businessDays(new Date("2025-12-01"), new Date("2025-12-07"))); // 5(平日のみ)
JavaScript
  • ポイント: 祝日は別途リスト化して除外。まずは土日除外の骨格から。

丸めの指針(目的別)

  • 経過時間の“おおよそ何日?”を知りたい:
    • 四捨五入: Math.round((d2 – d1) / msPerDay)
  • 締切まで“あと何日残っているか”を“端数切り捨て”で知りたい:
    • 切り捨て: Math.floor((d2 – d1) / msPerDay)
  • “1分でも過ぎたら翌日扱い”にしたい集計など:
    • 切り上げ: Math.ceil((d2 – d1) / msPerDay)
  • 暦日差(12/01から12/05は常に4日)を安定させたい:
    • UTCで日付丸め: calendarDayDiff を使う

よくある落とし穴と対策

  • 落とし穴: DST(夏時間)で1日が24時間でない日がある
    • 対策: 暦日差は UTC の「日境界」を使う(calendarDayDiff)。経過時間ベースならミリ秒差→割り算で良いが、丸めの意味を明確に。
  • 落とし穴: ローカルタイムゾーンの違いで日境界がずれる
    • 対策: APIや保存用は ISO(UTC)基準、表示/暦日計算は“意図したTZ”で揃える(例: Asia/Tokyo)。
  • 落とし穴: “含む/含まない”が不明確で1日ズレる
    • 対策: 仕様として「開始日を含むか」「終了日を含むか」を決め、+1/-1 を明示。
  • 落とし穴: 時刻を含む比較で端数が出る
    • 対策: 暦日計算なら対象を“その日の0時”へそろえてから差分計算。

練習問題(手を動かして覚える)

  • 1. 経過日数(小数)と丸め違いを比較
const d1 = new Date("2025-12-01T10:00:00+09:00");
const d2 = new Date("2025-12-05T08:00:00+09:00");
const msPerDay = 1000 * 60 * 60 * 24;
const raw = (d2 - d1) / msPerDay;
console.log(raw, Math.floor(raw), Math.round(raw), Math.ceil(raw));
JavaScript
  • 2. 暦日差(UTCで安定)
console.log(calendarDayDiff(new Date("2025-12-01"), new Date("2025-12-05"))); // 4
JavaScript
  • 3. 今日を含めた残り日数
console.log(inclusiveDaysUntil(new Date("2025-12-10")));
JavaScript
  • 4. 平日だけ数える(週末除外)
console.log(businessDays(new Date("2025-12-01"), new Date("2025-12-07"))); // 5
JavaScript

直感的な指針

  • 経過時間の差: “ミリ秒差 ÷ 86,400,000”。丸めは目的次第。
  • 暦日差を安定: UTCで日境界をそろえて計算。
  • 含む/含まない: 仕様を言葉で決めて +1/-1 で調整。
  • TZ/DSTの影響: 表示と保存、経過時間と暦日差を分けて考える。
タイトルとURLをコピーしました