引き算するとミリ秒が返ります。86400000 で割れば日数ですが、時刻が混ざると1日ずれます。日付だけに揃えてから引く形、負の差、月をまたぐ場合、年齢の数え方まで実行して確かめます。
答え
引き算するとミリ秒が返ります。
example.js
const from = new Date(2026, 8, 1);
const to = new Date(2026, 8, 8);
const ms = to - from;
console.log(ms);
console.log(ms / 86400000);
出力書き換えて実行できます
604800000
7
javascript
const from = new Date(2026, 8, 1, 23, 0);
const to = new Date(2026, 8, 2, 1, 0);
console.log((to - from) / 86400000);
console.log(Math.floor((to - from) / 86400000));
0.08333333333333333
0
86400000 は1日のミリ秒(24 * 60 * 60 * 1000)です。
new Date(2026, 8, 1) の月は0から数えるので、これは9月1日です。
→ Date — 作る・比べる・差を出す
時刻が混ざると1日ずれる
ここが本当の落とし穴です。
example.js
function toDay(date) {
return new Date(date.getFullYear(), date.getMonth(), date.getDate());
}
const from = new Date(2026, 8, 1, 23, 0);
const to = new Date(2026, 8, 2, 1, 0);
console.log((toDay(to) - toDay(from)) / 86400000);
出力書き換えて実行できます
1
example.js
const a = new Date(2026, 0, 31);
const b = new Date(2026, 1, 1);
console.log((b - a) / 86400000);
console.log((a - b) / 86400000);
console.log(Math.abs((a - b) / 86400000));
出力書き換えて実行できます
1
-1
1
日をまたいでいるのに 0 日です。
差は2時間しかないので、当然といえば当然です。
「何日前か」を出したいなら、先に時刻を落としてください。
example.js
const from = new Date(2026, 8, 1);
const to = new Date(2026, 8, 3, 12, 0);
const days = (to - from) / 86400000;
console.log(days);
console.log(Math.floor(days), Math.round(days), Math.ceil(days));
出力書き換えて実行できます
2.5
2 3 3
example.js
const from = new Date(2026, 8, 8, 9, 0);
const to = new Date(2026, 8, 8, 17, 30);
const ms = to - from;
console.log(ms / 60000);
console.log(ms / 3600000);
console.log(Math.floor(ms / 3600000) + '時間' + ((ms / 60000) % 60) + '分');
出力書き換えて実行できます
510
8.5
8時間30分
求めているのが経過時間なのか日付の枚数なのかを、先に決めてください。
この2つは別のものです。
| 知りたいこと |
書き方 |
| 経過した時間 |
そのまま引く |
| 日付が何枚またいだか |
0時に揃えてから引く |
順番が逆だと負になる
example.js
function isSameDay(a, b) {
return (
a.getFullYear() === b.getFullYear() &&
a.getMonth() === b.getMonth() &&
a.getDate() === b.getDate()
);
}
console.log(isSameDay(new Date(2026, 8, 8, 1), new Date(2026, 8, 8, 23)));
console.log(isSameDay(new Date(2026, 8, 8, 23), new Date(2026, 8, 9, 1)));
出力書き換えて実行できます
true
false
example.js
const relative = new Intl.RelativeTimeFormat('ja-JP', { numeric: 'auto' });
console.log(relative.format(-1, 'day'));
console.log(relative.format(-3, 'day'));
console.log(relative.format(2, 'day'));
console.log(relative.format(-1, 'month'));
出力書き換えて実行できます
昨日
3 日前
明後日
先月
月をまたいでも、月末の日数を気にする必要はありません。
内部では通し番号のミリ秒で持っているからです。
「何日前か」を表示するなら Math.abs() を使うか、
負のまま出さないようどちらが先かを決めてください。
割り切れないことがある
日数に直すとき、Math.round() と Math.floor() で結果が変わります。
javascript
const birth = new Date(2000, 8, 9);
const today = new Date(2026, 8, 8);
console.log(Math.floor((today - birth) / 86400000 / 365));
26
example.js
function age(birth, today) {
const years = today.getFullYear() - birth.getFullYear();
const beforeBirthday =
today.getMonth() < birth.getMonth() ||
(today.getMonth() === birth.getMonth() && today.getDate() < birth.getDate());
return beforeBirthday ? years - 1 : years;
}
console.log(age(new Date(2000, 8, 9), new Date(2026, 8, 8)));
console.log(age(new Date(2000, 8, 8), new Date(2026, 8, 8)));
出力書き換えて実行できます
25
26
「2日半」を2日と呼ぶか3日と呼ぶかは仕様です。
0時に揃えてから引けば、この迷いはそもそも起きません。
→ 四捨五入と桁の丸め
時間・分で出す
割る数を変えるだけです。
| 欲しい単位 |
割る数 |
| 秒 |
1000 |
| 分 |
60000 |
| 時間 |
3600000 |
| 日 |
86400000 |
example.js
const iso = new Date('2026-09-08');
const slash = new Date('2026/09/08');
console.log(iso.toISOString());
console.log(iso.getTime() === slash.getTime());
出力書き換えて実行できます
2026-09-08T00:00:00.000Z
false
「同じ日か」を知りたいだけなら
差を出す必要はありません。
引き算より読みやすく、時刻の混入で間違えることもありません。
「3日前」と表示する
自分で組み立てず、Intl に任せてください。
numeric: 'auto' を付けると、1日前は「昨日」になります。
言語を渡しているので、読み手の環境によって変わりません。
言語を省くと読み手の設定で変わります。このサイトの掲載出力が環境で変わらないよう、必ず 'ja-JP' のように書いています。
年齢を数える
日数から割り出さないでください。
誕生日は明日なので、正しくは 25 です。
1年を365日として割っているので、うるう年の分だけ先に進んでしまいます。
年数が大きいほどずれます。
年・月・日で比べてください。
誕生日の当日に1つ増えます。
文字列から作るときの注意
2026-09-08(ハイフン)… 協定世界時の0時
2026/09/08(スラッシュ)… その場所の0時
日本で動かすと9時間ずれます。
同じ書式で揃えるか、new Date(2026, 8, 8) のように成分から作ってください。
片方をハイフン、もう片方をスラッシュで作って引き算すると、答えが9時間分だけ狂います。
→ 日付を書式どおりに整える
実務では何を使うか
- 差を出すだけなら、標準の
Date で足ります。この記事の書き方で十分です
- 「3日前」「先月の同じ日」のような日付の計算が増えるなら、
専用のライブラリを検討してください。月末の扱いで必ず悩みます
- 時間帯をまたぐ集計をするなら、どの地域の0時かを最初に決めてください
標準にも新しい日付の仕組み(Temporal)が入りつつありますが、動く環境がまだ限られます。使う前に、対象の環境で確かめてください。
まとめ
- 引き算で返るのはミリ秒。
86400000 で割ると日数
- 時刻が入っていると日をまたいでも0日になる
- 「日付の枚数」を数えるなら0時に揃えてから引く
- 順番が逆なら負になる。
Math.abs() か、順番を決める
- 年齢は日数から割り出さない。 年・月・日で比べる
- 「同じ日か」だけなら引き算せずに年・月・日で比べる
- 「3日前」の表示は
Intl.RelativeTimeFormat に任せる
- ハイフンとスラッシュで基準の時間帯が変わる