【JavaScript】日時の差分を計算する方法|日数・時間・分・秒・月差分・年齢計算・相対表示(○日前)まで解説

「あと何日」「何時間前」「年齢は何歳」など、2 つの日時の差分を計算する処理は Web 開発で頻出します。JavaScript では Date オブジェクト同士の減算でミリ秒の差分が得られ、そこから日数・時間・分・秒に変換できます。この記事ではミリ秒ベースの基本から、月差分・年齢計算・相対表示(「3日前」)まで体系的に解説します。

この記事でわかること
・2 つの Date の差分をミリ秒で取得する方法
・ミリ秒を日数・時間・分・秒に変換する方法
・月の差分・年の差分の計算
・年齢計算(誕生日から現在まで)
・相対表示(「3 日前」「2 時間後」)のフォーマット
・Intl.RelativeTimeFormat による国際化対応
・performance.now() による経過時間計測
・夏時間・タイムゾーンの注意点
スポンサーリンク

ミリ秒単位で差分を取得する

Date オブジェクト同士は減算演算子で直接計算でき、結果はミリ秒で返ります。

JavaScript
const date1 = new Date("2026-03-01T10:00:00");
const date2 = new Date("2026-04-15T18:30:00");

const diffMs = date2 - date1;
console.log(diffMs); // 3902600000(ミリ秒)

このミリ秒をもとに、日・時間・分・秒に変換していきます。

変換に使う定数

単位 1単位あたりのミリ秒 定数
1 秒 1,000 1000
1 分 60,000 1000 * 60
1 時間 3,600,000 1000 * 60 * 60
1 日 86,400,000 1000 * 60 * 60 * 24

日数・時間・分・秒に変換する

単一の単位に変換する

JavaScript
const diffMs = new Date("2026-04-15") - new Date("2026-03-01");

// 日数
const days = Math.floor(diffMs / (1000 * 60 * 60 * 24));
console.log(days); // 45

// 時間数
const hours = Math.floor(diffMs / (1000 * 60 * 60));
console.log(hours); // 1080

// 分数
const minutes = Math.floor(diffMs / (1000 * 60));
console.log(minutes); // 64800

日・時間・分・秒に分解する

JavaScript
function dateDiff(start, end) {
  const ms = Math.abs(end - start);

  const days    = Math.floor(ms / (1000 * 60 * 60 * 24));
  const hours   = Math.floor((ms % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
  const minutes = Math.floor((ms % (1000 * 60 * 60)) / (1000 * 60));
  const seconds = Math.floor((ms % (1000 * 60)) / 1000);

  return { days, hours, minutes, seconds };
}

const result = dateDiff(
  new Date("2026-03-31T10:00:00"),
  new Date("2026-04-02T15:30:45")
);
console.log(result);
// { days: 2, hours: 5, minutes: 30, seconds: 45 }

// フォーマットして表示
console.log(`${result.days}日${result.hours}時間${result.minutes}分${result.seconds}秒`);
// "2日5時間30分45秒"
Math.abs() で絶対値を取ることで、start と end の順序に関係なく正の差分が得られます。

月の差分・年の差分を計算する

月や年の差分はミリ秒の単純な割り算では計算できません(月の日数は 28〜31 日で一定でないため)。年・月の各コンポーネントを使って計算します。

月の差分
function monthDiff(start, end) {
  return (end.getFullYear() - start.getFullYear()) * 12
       + (end.getMonth() - start.getMonth());
}

console.log(monthDiff(
  new Date("2025-06-15"),
  new Date("2026-03-20")
)); // 9
年の差分
function yearDiff(start, end) {
  return end.getFullYear() - start.getFullYear();
}

console.log(yearDiff(
  new Date("2020-01-01"),
  new Date("2026-03-31")
)); // 6
月差分は「月の数の差」であり、日付部分は考慮していません。例えば 1/31 と 2/1 は月差分 1 ですが実際は 1 日差です。日付部分まで正確に考慮するには date-fns の differenceInMonths などライブラリの利用を検討してください。

年齢を計算する(誕生日から現在まで)

JavaScript
function calcAge(birthday) {
  const today = new Date();
  let age = today.getFullYear() - birthday.getFullYear();

  // 今年の誕生日がまだ来ていなければ -1
  const monthDiff = today.getMonth() - birthday.getMonth();
  if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthday.getDate())) {
    age--;
  }

  return age;
}

console.log(calcAge(new Date("1990-08-15"))); // 35(2026年3月時点)
console.log(calcAge(new Date("2000-12-25"))); // 25(2026年3月時点)
年齢計算は「今年の誕生日が過ぎたかどうか」で 1 歳の差が出ます。単純な年の減算だけでは不正確になるため、月と日の比較が必要です。

相対表示(「3 日前」「2 時間後」)にフォーマットする

SNS やブログでよく見る「3 日前」「たった今」のような表示を実装します。

JavaScript
function timeAgo(date) {
  const now = new Date();
  const diffMs = now - date;
  const diffSec = Math.floor(diffMs / 1000);
  const diffMin = Math.floor(diffSec / 60);
  const diffHour = Math.floor(diffMin / 60);
  const diffDay = Math.floor(diffHour / 24);
  const diffMonth = Math.floor(diffDay / 30);
  const diffYear = Math.floor(diffDay / 365);

  if (diffSec < 60)   return "たった今";
  if (diffMin < 60)   return `${diffMin}分前`;
  if (diffHour < 24)  return `${diffHour}時間前`;
  if (diffDay < 30)   return `${diffDay}日前`;
  if (diffMonth < 12) return `${diffMonth}ヶ月前`;
  return `${diffYear}年前`;
}

// 使用例
console.log(timeAgo(new Date(Date.now() - 3 * 60 * 1000)));     // "3分前"
console.log(timeAgo(new Date(Date.now() - 5 * 24 * 3600000)));  // "5日前"

Intl.RelativeTimeFormat で国際化対応する

手動で「〇日前」を組み立てる代わりに、Intl.RelativeTimeFormat を使うとロケールに応じた相対表示が自動生成されます。

JavaScript
const rtf = new Intl.RelativeTimeFormat("ja", { numeric: "auto" });

console.log(rtf.format(-1, "day"));   // "昨日"
console.log(rtf.format(-3, "day"));   // "3 日前"
console.log(rtf.format(1, "hour"));   // "1 時間後"
console.log(rtf.format(-2, "month")); // "2 か月前"
console.log(rtf.format(0, "day"));    // "今日"
numeric オプション 0 の場合 -1 の場合
"always"(デフォルト) “0 日前” “1 日前”
"auto" “今日” “昨日”
numeric: "auto" を指定すると「昨日」「今日」「明日」のような自然な表現になります。

処理の経過時間を計測する(performance.now)

日付の差分ではなく、コードの実行時間を計測するには performance.now() を使います。Date よりも高精度(マイクロ秒単位)です。

JavaScript
const start = performance.now();

// 計測したい処理
const arr = Array.from({ length: 100000 }, (_, i) => i);
arr.sort(() => Math.random() - 0.5);

const end = performance.now();
console.log(`実行時間: ${(end - start).toFixed(2)}ms`);
// "実行時間: 42.35ms"
方法 精度 用途
Date.now() ミリ秒 日時の差分(日・時間・分)
performance.now() マイクロ秒 処理速度の計測(ベンチマーク)

夏時間・タイムゾーンの注意点

日数の差分を diffMs / 86400000 で計算すると、夏時間(DST)切り替えのある地域では誤差が発生する場合があります。

JavaScript
// 夏時間切り替え日をまたぐ場合(米国の例)
const d1 = new Date("2026-03-08T00:00:00"); // DST開始前
const d2 = new Date("2026-03-09T00:00:00"); // DST開始後

// 実際には23時間しか経過していないため
// (d2 - d1) / 86400000 = 0.9583... → Math.floor で 0日になる可能性
日本は夏時間がないため国内向けアプリでは問題になりませんが、グローバル対応のアプリでは注意が必要です。UTC ベースで計算する(Date.UTC() を使う)か、date-fns-tz などの TZ 対応ライブラリを利用してください。

関連記事

よくある質問

Q2つの日付の差分を日数で取得するにはどうすればよいですか?
AMath.floor((date2 - date1) / (1000 * 60 * 60 * 24)) で日数が得られます。Date オブジェクト同士の減算はミリ秒を返すので、1 日のミリ秒数(86,400,000)で割ります。
Q月の差分をミリ秒で計算できないのはなぜですか?
A月の日数は 28〜31 日で一定ではないため、ミリ秒を「1 ヶ月」で割ることができません。月の差分は (endYear - startYear) * 12 + (endMonth - startMonth) のように年・月のコンポーネントで計算します。
Q「3日前」のような相対表示を簡単に実装するには?
AIntl.RelativeTimeFormat を使えば、rtf.format(-3, "day")"3 日前" が自動生成されます。ロケールを変えるだけで英語やその他の言語にも対応できます。
Qperformance.now() と Date.now() はどう使い分けますか?
A日付の計算(日数・時間の差分)には Date.now()、コードの実行速度の計測(ベンチマーク)には performance.now() を使います。performance.now() はマイクロ秒精度で、ページ読み込みからの経過時間を返します。
Q夏時間の影響で日数計算がずれることはありますか?
Aはい。夏時間の切り替え日をまたぐ場合、1 日が 23 時間や 25 時間になるため Math.floor の結果がずれることがあります。日本は夏時間がないため影響を受けませんが、グローバル対応では UTC ベースの計算か TZ 対応ライブラリを使ってください。

まとめ

JavaScript で日時の差分を計算する方法を整理しました。

  • 基本: date2 - date1 でミリ秒差分を取得し、日・時間・分・秒に変換
  • 月差分: 年×12 + 月で計算(ミリ秒の割り算では不可)
  • 年齢計算: 年の差分 + 誕生日が過ぎたかの判定
  • 相対表示: Intl.RelativeTimeFormat で「3日前」「昨日」を自動生成
  • 計測: 処理速度には performance.now() を使用

日数や時間の差分はミリ秒ベースの計算でシンプルに実装できますが、月差分や年齢計算は個別のロジックが必要です。SNS のような相対表示には Intl.RelativeTimeFormat が便利なので、ぜひ活用してください。