時間の差分計算:時刻同士の引き算と表記

約4分

「9:00 から 17:30 まで何時間?」「3 日 4 時間 後の時刻は?」など、時間の差分計算は日常的に必要ですが、日付をまたぐケースや負の値で混乱しやすい分野です。本記事では時間差分の計算方法を整理します。

基本の引き算

「9:00 から 17:30」の差:

17:30 - 09:00 = 8:30(8 時間 30 分)

時刻を「分」に変換すると簡単:

17:30 → 17 × 60 + 30 = 1050 分
09:00 →  9 × 60 +  0 =  540 分
差 = 1050 - 540 = 510 分 = 8 時間 30 分

日付をまたぐケース

「23:00 から翌日 7:00」の差:

7:00 - 23:00 = -16:00(負の値)

これは間違い。日付をまたぐ場合は +24 時間

(7 + 24):00 - 23:00 = 31:00 - 23:00 = 8:00

または日付情報も含めて計算:

2024-01-02 07:00 - 2024-01-01 23:00 = 8 時間

日付をまたぐ判定

シンプルなルール:

let diff = end - start; // 分
if (diff < 0) diff += 24 * 60; // 日をまたいだら +24 時間

ただし「2 日以上空く」場合はこの単純な式では足りない。日付を含めて計算するのが安全。

サマータイムと夏時間

夏時間(DST)開始日は 23 時間、終了日は 25 時間:

  • 春のある日:3:00 直前が 4:00 になる → その日は 23 時間
  • 秋のある日:2:00 が 1:00 に戻る → その日は 25 時間

「24 時間 = 1 日」と仮定するとずれる。UTC で計算するか、ライブラリ(date-fns、Luxon など)を使う。

日本は夏時間がないので無視できるが、グローバル対応では考慮必須。

ISO 8601 の期間表記

「期間(duration)」の標準表記:

P3Y2M5D     — 3 年 2 ヶ月 5 日
PT2H30M     — 2 時間 30 分
P1DT12H     — 1 日と 12 時間
P1W         — 1 週間
  • P で始まる
  • T の前は日付要素、後は時刻要素
  • Y(年)、M(月、T 前)、W(週)、D(日)、H(時)、M(分、T 後)、S(秒)

API のレスポンスや YouTube の動画長などで使われる:

PT4M13S  → 4 分 13 秒

人間に読みやすい表記

「3 時間 25 分前」「明日の朝」のような表現を相対時刻と呼ぶ:

// JavaScript の Intl.RelativeTimeFormat
const rtf = new Intl.RelativeTimeFormat('ja', { numeric: 'auto' });
rtf.format(-1, 'day'); // "昨日"
rtf.format(2, 'hour'); // "2 時間後"
rtf.format(-30, 'minute'); // "30 分前"

英語では:

const rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' });
rtf.format(-1, 'day'); // "yesterday"
rtf.format(2, 'hour'); // "in 2 hours"

経過時間の表示

「経過 1 時間 23 分 45 秒」のような表記:

function formatDuration(seconds) {
	const h = Math.floor(seconds / 3600);
	const m = Math.floor((seconds % 3600) / 60);
	const s = seconds % 60;
	return `${h}:${String(m).padStart(2, '0')}:${String(s).padStart(2, '0')}`;
}

formatDuration(5025); // "1:23:45"

YouTube のタイムスタンプや動画再生時間で見る形式。

時間の四則演算

日時に「時間を足す」:

const start = new Date('2024-01-15T10:00:00');
const end = new Date(start.getTime() + 90 * 60 * 1000); // +90 分
end.toISOString(); // "2024-01-15T11:30:00.000Z"

「時刻を分に変換 → 計算 → 戻す」が基本。

Date.getTime() はミリ秒なので:

  • 1 秒 = 1000
  • 1 分 = 60,000
  • 1 時間 = 3,600,000
  • 1 日 = 86,400,000

営業時間の計算

「9:00〜18:00 の営業時間で 3 時間 30 分作業した」:

  • 単純に時刻を足すだけ
  • ただし昼休み(12:00〜13:00)を除外するなら別途計算

実装例:

function workHoursInRange(start, end, breakStart, breakEnd) {
	let total = end - start;
	if (start < breakEnd && end > breakStart) {
		const overlap = Math.min(end, breakEnd) - Math.max(start, breakStart);
		total -= overlap;
	}
	return total;
}

月・年を含む期間

「1 年と 3 ヶ月後」の計算:

  • 月数は固定的でない(28, 29, 30, 31 日)
  • 年は閏年で 366 日
  • 「1 ヶ月後の同じ日」のような表現が必要
function addMonths(date, months) {
	const d = new Date(date);
	const targetMonth = d.getMonth() + months;
	d.setDate(1);
	d.setMonth(targetMonth);
	// 元の日が新月の最終日を超える場合の処理
	const lastDay = new Date(d.getFullYear(), d.getMonth() + 1, 0).getDate();
	d.setDate(Math.min(date.getDate(), lastDay));
	return d;
}

「3 月 31 日 + 1 ヶ月 = 4 月 30 日」のような月末処理が必要。

時間の単位変換

単位秒換算
1
60
3,600
86,400
604,800
月(30 日換算)2,592,000
年(365 日換算)31,536,000

「100 万秒は何日?」 → 1,000,000 / 86,400 ≒ 11.57 日

タイムゾーンを含む差分

「東京の 10:00 と NY の 21:00(前日)」の差:

  • 東京 = UTC+9
  • NY = UTC-5(夏時間で UTC-4)
  • 差は 14 時間(夏時間中は 13 時間)

UTC に揃えてから引き算するのが安全:

const tokyo = new Date('2024-01-15T10:00:00+09:00');
const ny = new Date('2024-01-14T21:00:00-05:00');
const diff = (tokyo - ny) / (1000 * 60 * 60); // 0 時間(同時刻)

24 時間制と 12 時間制

  • 24 時間制:00:00〜23:59
  • 12 時間制:12:00 AM〜11:59 PM

12 時間制での落とし穴:

  • 12:00 AM = 真夜中(0:00)
  • 12:00 PM = 正午(12:00)
  • 12:01 AM ≠ 12:01 PM(12 時間ずれる)

API やデータベースは 24 時間制で扱うのが安全。

まとめ

  • 時刻の差は「分に変換 → 引き算 → 戻す」が基本
  • 日付をまたぐなら +24 時間または日付込みで計算
  • ISO 8601 期間表記は P3Y2M5D PT2H30M
  • 月・年は単純な秒換算ではない
  • タイムゾーン跨ぎは UTC で計算

時間の差分や経過時間の計算には、本サイトの時間計算ツールが使えます。