📅 Date Difference Calculator
Days, weeks, months, working days between any two dates.
Last updated: June 9, 2026 · By Λ
By Λ · Updated June 9, 2026 · ~3 min read
Why I added this tool
I needed to count working days between two project milestones for a contract estimate, ended up wrestling with three browser tabs and a JavaScript console, and decided that was the last time I would do that. This is a date difference calculator that handles the common gotchas: timezone-aware times, working-days-only mode, and a breakdown in human units (years/months/days) as well as the raw total in each unit.
How the numbers are computed
Both dates (plus optional times) become local timestamps, and the gap is measured in milliseconds. The total cards are plain divisions of that gap: Days divides by 86,400,000 and rounds down, Weeks divides days by 7, Months (avg) by 30.44, Years (avg) by 365.25. The headline breakdown instead counts real calendar fields, borrowing actual month lengths when the day underflows. Working-day counting steps through each date after the start one, ticking up only on Monday through Friday. Every figure comes from script running on your own machine, so the dates you type stay inside the tab and are never transmitted anywhere.
A worked example
Set the start to 2026-01-05, the end to 2026-02-20, leave the times at 00:00, and tick the working-days box. The breakdown reads 0 years, 1 months, 15 days; the cards show 46 days, 34 working days, 6.57 weeks, 1.51 average months, 1,104 hours, 66,240 minutes, 3,974,400 seconds. A shift on 2026-06-09 from 09:30 to 17:45 gives 0 days, 8 hours, 495 minutes, 29,700 seconds.
What "working days" actually means
The working-days toggle excludes Saturdays and Sundays. It does not exclude holidays, because holidays vary wildly by country, region, and even company. If you need US federal holidays, UK bank holidays, or your team's specific PTO calendar, you will need to subtract those manually. I deliberately did not bake in a country picker because the moment you do that, someone wants their region added, and the maintenance becomes endless.
Edge cases this handles correctly
Leap years and DST. Calculations use JavaScript's native Date arithmetic which accounts for both. A "year" added to February 29 lands on February 28 the following non-leap year, which is the conventional behavior.
Same-day with different times. If you pick the same date but different times, you get hours and minutes. Useful for shift calculations.
End before start. The result is shown as the absolute difference, but the breakdown notes which direction.
Very long ranges. Anything up to about 2.7 million years works without precision issues. For longer ranges, JavaScript's 64-bit floats start losing day-level resolution.
Where it can surprise you
Because the Days card rounds down, 23 hours and 59 minutes displays as 0 days. The same flooring interacts with daylight saving: a midnight-to-midnight range crossing a spring-forward jump is genuinely an hour short, which can shave a unit off the day count. The working-day tally also begins the day after your start date, so the start day itself is never counted.
Frequently Asked Questions
Why do the Months (avg) and Years (avg) cards disagree with the headline breakdown?
The cards divide total days by fixed averages (30.44 and 365.25); the headline counts actual calendar fields. Both are correct, they just answer different questions.
Are the start and end dates included in the working-day count?
The counter starts the day after the start date and runs through the end date, so a weekday start is left out while a weekday end counts.
Why did my midnight-to-midnight range come out an hour short?
It crossed a daylight saving transition, so the elapsed time really is 23 hours on the affected day.
Does the Swap button exchange the times too?
Yes. Swap trades both dates and both time fields, then recalculates.
Related
For converting times across time zones, see the timezone converter. For parsing Unix timestamps, see the timestamp converter. For visualizing cron schedules and seeing the next N runs of a job, see the cron parser.