時間の差分計算:時刻同士の引き算と表記
「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 期間表記は
P3Y2M5DPT2H30M - 月・年は単純な秒換算ではない
- タイムゾーン跨ぎは UTC で計算
時間の差分や経過時間の計算には、本サイトの時間計算ツールが使えます。