"How many days until the deadline?" sounds trivial until you actually write the code and get bitten by time zones, daylight saving time, and off-by-one errors. Here's a clear, correct way to do it.
The naive version (and why it's slightly wrong)
The classic one-liner subtracts two Date objects and divides by the number of milliseconds in a day:
const msPerDay = 1000 * 60 * 60 * 24;
function daysBetween(a, b) {
return Math.round((b - a) / msPerDay);
}
daysBetween(new Date("2026-01-01"), new Date("2026-03-01")); // 59
This works most of the time, but it silently breaks across a daylight-saving boundary, where a "day" is 23 or 25 hours long. Math.round hides the error for short ranges and produces off-by-one results for longer ones.
The correct version: normalize to UTC midnight
Strip the time component by converting both dates to UTC midnight before subtracting. Now every day is exactly 24 hours:
function daysBetween(a, b) {
const utcA = Date.UTC(a.getFullYear(), a.getMonth(), a.getDate());
const utcB = Date.UTC(b.getFullYear(), b.getMonth(), b.getDate());
const msPerDay = 1000 * 60 * 60 * 24;
return Math.round((utcB - utcA) / msPerDay);
}
Because we've zeroed out hours, minutes, and seconds, DST no longer matters — the subtraction is always a whole number of days.
Inclusive vs. exclusive counting
One question trips people up: does the count include both endpoints? "From the 1st to the 3rd" is 2 days if you count gaps, but 3 days if you count calendar days touched. Decide which your feature needs and add + 1 for the inclusive version. Being explicit about this in your UI saves a lot of support tickets.
Don't reinvent it every time
For a quick answer without writing code, I use CalcPine's days between dates calculator — it handles the inclusive/exclusive distinction and shows the breakdown in years, months, and days, which is handy for sanity-checking your own implementation.
Reaching for a library?
If you're already pulling in a date library, date-fns has differenceInCalendarDays(b, a) and Luxon has DateTime.diff. Both normalize calendar days for you. But for a single count, the UTC-midnight trick above is a dependency-free four-liner worth keeping in your snippets folder.
Happy shipping.
Top comments (0)