「あと何日」「何時間前」「年齢は何歳」など、2 つの日時の差分を計算する処理は Web 開発で頻出します。JavaScript では Date オブジェクト同士の減算でミリ秒の差分が得られ、そこから日数・時間・分・秒に変換できます。この記事ではミリ秒ベースの基本から、月差分・年齢計算・相対表示(「3日前」)まで体系的に解説します。
この記事でわかること
・2 つの Date の差分をミリ秒で取得する方法
・ミリ秒を日数・時間・分・秒に変換する方法
・月の差分・年の差分の計算
・年齢計算(誕生日から現在まで)
・相対表示(「3 日前」「2 時間後」)のフォーマット
・Intl.RelativeTimeFormat による国際化対応
・performance.now() による経過時間計測
・夏時間・タイムゾーンの注意点
・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 対応ライブラリを利用してください。関連記事
- 日付を操作する方法 — 加算・減算・比較・月末取得
- 日付を取得する方法 — Date オブジェクト・年月日時分秒・フォーマット
- 日付のフォーマットを変換する方法
- setInterval の使い方 — カウントダウンタイマーの実装
- カウントダウンタイマーの作成
- Intl API を使った日付・数値の国際化フォーマット
よくある質問
Q2つの日付の差分を日数で取得するにはどうすればよいですか?
A
Math.floor((date2 - date1) / (1000 * 60 * 60 * 24)) で日数が得られます。Date オブジェクト同士の減算はミリ秒を返すので、1 日のミリ秒数(86,400,000)で割ります。Q月の差分をミリ秒で計算できないのはなぜですか?
A月の日数は 28〜31 日で一定ではないため、ミリ秒を「1 ヶ月」で割ることができません。月の差分は
(endYear - startYear) * 12 + (endMonth - startMonth) のように年・月のコンポーネントで計算します。Q「3日前」のような相対表示を簡単に実装するには?
A
Intl.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 が便利なので、ぜひ活用してください。