JavaScript Tips | 日付・時間ユーティリティ:日付差分

JavaScript JavaScript
スポンサーリンク
スポンサーリンク

日付差分は「2つの日付の距離を正しく数値化する技術」

日付・時間ユーティリティの中でも 日付差分(date difference)は、業務システムで非常に重要な処理です。 請求書の支払期限、予約の残り日数、勤怠の勤務日数、キャンペーンの残り期間など、 「A と B の日付の差を何日・何時間・何分と表すか」はあらゆる場面で登場します。

しかし、JavaScript の Date は扱い方を間違えると簡単にズレが発生します。 特に 月は 0 始まりタイムゾーンの影響時刻を含めるかどうかなどが初心者の落とし穴です。

ここでは、日付差分の基本から、実務で使えるテンプレートまでを 例題・コードを交えて丁寧に解説します。

日付差分の基本は「ミリ秒の差」を使うこと

JavaScript の Date は内部的に 1970年1月1日からのミリ秒数(タイムスタンプ)を保持しています。 そのため、日付差分は次のように ミリ秒の差を計算するのが最も安全です。

const a = new Date("2026-05-01");
const b = new Date("2026-05-10");

const diffMs = b.getTime() - a.getTime();
console.log(diffMs);
JavaScript

ミリ秒 → 日数への変換

const diffDays = diffMs / (1000 * 60 * 60 * 24);
console.log(diffDays); // 9
JavaScript

ここで重要なのは、 日付差分は「ミリ秒 → 日数」へ変換することで正確に計算できるという点です。

日付差分ユーティリティ(最小構成)

まずは最もシンプルで実務でも使える形を紹介します。

function diffInDays(a, b) {
  const msA = new Date(a).getTime();
  const msB = new Date(b).getTime();
  const diffMs = msB - msA;
  return diffMs / (1000 * 60 * 60 * 24);
}
JavaScript

使い方は次の通りです。

console.log(diffInDays("2026-05-01", "2026-05-10")); // 9
JavaScript

この関数が業務で強い理由

  • 常に数値(日数)を返す
  • 時刻の影響を受けない(ISO形式なら安全)
  • ミリ秒計算なのでズレが起きにくい

初心者がやりがちなミス(年月日を直接引き算するなど)をすべて吸収してくれます。

「時刻を無視して日付差分を計算したい」場合の注意点

業務では「日付だけで差分を計算したい」場面が非常に多いです。

例:

  • 締め日まであと何日か
  • イベントまでの残り日数
  • 勤怠の勤務日数

しかし、次のようなケースでズレが発生します。

diffInDays("2026-05-01T23:59", "2026-05-02T00:01"); // ほぼ0日
JavaScript

「日付としては 1 日差」なのに、ミリ秒ではほぼ差がありません。

解決方法:時刻を 00:00:00 に揃えてから計算する

function normalizeDate(date) {
  const d = new Date(date);
  d.setHours(0, 0, 0, 0);
  return d;
}

function diffInDaysPure(a, b) {
  const d1 = normalizeDate(a);
  const d2 = normalizeDate(b);
  const diffMs = d2.getTime() - d1.getTime();
  return diffMs / (1000 * 60 * 60 * 24);
}
JavaScript

使い方は次の通りです。

console.log(diffInDaysPure("2026-05-01T23:59", "2026-05-02T00:01")); // 1
JavaScript

重要ポイント

  • 時刻をリセットすることで「日付だけの差分」が正しく計算できる
  • 業務ではこの方法が非常に多く使われる

日付差分ユーティリティ(業務で使えるテンプレート)

実務では、日数だけでなく「時間差」「分差」「秒差」も必要になるため、 次のようなユーティリティをまとめておくと便利です。

export const DateDiffUtil = {
  ms(a, b) {
    return new Date(b).getTime() - new Date(a).getTime();
  },

  seconds(a, b) {
    return this.ms(a, b) / 1000;
  },

  minutes(a, b) {
    return this.ms(a, b) / (1000 * 60);
  },

  hours(a, b) {
    return this.ms(a, b) / (1000 * 60 * 60);
  },

  days(a, b) {
    return this.ms(a, b) / (1000 * 60 * 60 * 24);
  },

  // 日付だけ比較(時刻無視)
  pureDays(a, b) {
    const d1 = new Date(a);
    const d2 = new Date(b);
    d1.setHours(0, 0, 0, 0);
    d2.setHours(0, 0, 0, 0);
    return (d2.getTime() - d1.getTime()) / (1000 * 60 * 60 * 24);
  },
};
JavaScript

使い方は次の通りです。

import { DateDiffUtil } from "./DateDiffUtil.js";

console.log(DateDiffUtil.days("2026-05-01", "2026-05-10")); // 9
console.log(DateDiffUtil.hours("2026-05-01T10:00", "2026-05-01T15:00")); // 5
console.log(DateDiffUtil.pureDays("2026-05-01T23:59", "2026-05-02T00:01")); // 1
JavaScript

日付差分の“実務での落とし穴”を深掘りする

1. 日付文字列の形式によって結果が変わる

new Date("2026/05/01"); // Safari で失敗する可能性あり
JavaScript

非標準形式はブラウザ差異が出るため、 ISO形式(YYYY-MM-DD)か手動パースを使うのが安全です。

2. 時刻を含むかどうかで差分が大きく変わる

"2026-05-01T23:59""2026-05-02T00:01"
JavaScript

ミリ秒ではほぼ差がないが、 日付としては「1日差」です。

3. タイムゾーンの影響で差分がズレることがある

UTC とローカルタイムの扱いを混ぜるとズレが発生します。

例: new Date("2026-05-01") は UTC として解釈されるため、 JST(UTC+9)では前日になることがあります。

日付差分を使った実務テンプレート

締め日までの残り日数を計算する

function daysUntilClosing(today, closingDate) {
  return DateDiffUtil.pureDays(today, closingDate);
}

console.log(daysUntilClosing("2026-05-01", "2026-05-10")); // 9
JavaScript

キャンペーン終了までの残り時間を計算する

function hoursLeft(endDate) {
  return DateDiffUtil.hours(new Date(), endDate);
}
JavaScript

勤怠の勤務日数を計算する

function workDays(start, end) {
  return DateDiffUtil.pureDays(start, end) + 1; // 初日を含める
}
JavaScript

まとめ:日付差分は「ミリ秒計算」と「時刻を含めるかどうか」が鍵

日付差分を正しく扱うためのポイントは次の通りです。

  • ミリ秒の差を計算するのが最も安全
  • 日付だけ比較したい場合は時刻をリセットする
  • 非標準形式の日付文字列はブラウザ差異が出るので注意
  • タイムゾーンの違いで差分がズレることがある
  • 業務ではユーティリティ化して再利用するのが最も安全

日付差分は単純に見えて、実は多くの落とし穴があります。 しかし、正しいユーティリティを用意しておけば、 どの場面でも安定した計算ができるようになります。

業務システムの品質を支える重要な基盤として、 ぜひ日付差分ユーティリティを活用してください。

タイトルとURLをコピーしました