Date Calculations: Adding Days, Calculating Differences, and More
Learn how to calculate differences between dates, add/subtract time, and handle edge cases.
Why Date Math Is Harder Than It Looks (My Embarrassing Mistake)
Once, early in my career, I had to calculate the date 30 days from now. "Simple," I thought. "Just add 30 * 24 * 60 * 60 * 1000 milliseconds!"
So I shipped it, and of course, it broke when daylight saving time changed. Adding 720 hours doesn't always give you the same local time 30 days later! On days with DST changes, the day is 23 or 25 hours long.
That was a humbling lesson. Date math seems straightforward, but there are edge cases everywhere: months with different numbers of days, leap years, daylight saving time, time zones.
The good news is: You don't have to solve these problems yourself! Libraries handle them, and our Date Diff Calculator can help you see the results quickly.
Calculating the Difference Between Two Dates
This is one of the most common date operations, and it's surprisingly nuanced.
Do you want the difference in days? Weeks? Months? Years? All of the above?
**Simple difference in days:**
If you just need to know "how many days apart are these?", you can convert both dates to UTC at midnight and subtract.
But wait — what about time zones? If Date 1 is June 20 in New York, and Date 2 is June 21 in Tokyo, are they one day apart or two? It depends on what you're measuring!
**Human-readable difference:**
If you want "2 years, 3 months, 5 days", that's trickier. Months have different lengths, so you can't just divide by an average.
Most libraries have a function for this. In date-fns, it's `intervalToDuration`. In luxon, it's `diff` with `'months'` or `'years'`.
Our Date Diff Calculator shows you all the different ways to look at the difference between two dates — it's great for understanding the nuances!
Adding and Subtracting Time (The Right Way)
Here's rule #1 for adding time: Don't add milliseconds manually! Use a library that understands dates.
Why? Let's see:
- Adding 1 month to January 31 should give you February 28/29, not March 3
- Adding 1 day to March 12, 2023 in New York should give you March 13, even though the day was only 23 hours long
- Adding 1 year to February 29, 2024 should give you February 28, 2025
Good date libraries handle all this for you.
**In date-fns:**
import { addDays, addMonths, addYears } from 'date-fns';
const now = new Date();
const nextWeek = addDays(now, 7);
const nextMonth = addMonths(now, 1);
const nextYear = addYears(now, 1); **In luxon:**
import { DateTime } from 'luxon';
const now = DateTime.now();
const nextWeek = now.plus({ days: 7 });
const nextMonth = now.plus({ months: 1 }); Let the library worry about the edge cases — that's what they're for!
Leap Years: The 4-100-400 Rule (It's Tricky)
Leap years seem simple: Every 4 years! But it's actually more complicated than that.
The full rules are:
1. Divisible by 4? Maybe leap year
2. Unless it's also divisible by 100 — then not a leap year
3. Unless it's also divisible by 400 — then it is a leap year!
So:
- 2020: Leap year (div by 4, not by 100)
- 1900: Not a leap year (div by 4 and 100, not by 400)
- 2000: Leap year (div by 4, 100, and 400!)
- 2024: Leap year
- 2100: Will not be a leap year
This is another thing you never want to implement yourself. All good date libraries know the rules perfectly.
Practical Examples: Billing Cycles, Deadlines, and Schedules
Let's walk through some real-world scenarios I've had to implement:
**Scenario 1: 30-day billing cycle**
User signs up on January 15. When's their next bill? Feb 15. If they sign up on March 31, next bill is April 30. Not May 1! This is why you need proper date math, not just adding 30 days.
**Scenario 2: "End of month" calculations**
What's the last day of the current month? Don't hardcode! Most libraries have a function for this (date-fns has `lastDayOfMonth`).
**Scenario 3: Counting business days**
Need to calculate "5 business days from now"? This gets complicated because you need to exclude weekends and holidays. You'll need a holiday calendar for this — it's very domain-specific.
**Scenario 4: Age calculation**
Calculating someone's age from their birthday seems simple, but you have to be careful about whether they've had their birthday this year yet.
For all these scenarios, I recommend finding a library or existing solution before coding it yourself!
My Go-To Date Calculation Functions
Here are functions I reach for again and again:
**date-fns functions I use constantly:**
- `differenceInDays` — How many days between?
- `addDays` / `subDays` — Add/subtract days
- `addMonths` / `subMonths` — Add/subtract months
- `startOfMonth` / `endOfMonth` — Start/end of month
- `startOfWeek` / `endOfWeek` — Start/end of week
- `isSameDay` — Are two dates on the same day?
- `isBefore` / `isAfter` — Comparison without bugs
- `intervalToDuration` — Human-readable difference
**luxon methods I love:**
- `plus` / `minus` — Immutable time math
- `startOf` / `endOf` — Start/end of units
- `diff` — Calculate differences
- `toRelative` — Relative time strings
Whatever library you choose, learn the API well — it will save you so much time!
Try These Tools
Open the tools that go with this tutorial and practice what you learned.
Date Difference Calculator
Calculate the number of days, weeks, months, and years between two dates.
Date Formatter
Format dates and times in various formats including ISO, RFC, and custom patterns.
Timestamp Converter
Convert between UNIX timestamps, ISO 8601, and human-readable dates.
More Tutorials in This Category
Keep Learning
Time Zones: A Survival Guide for Weary Developers
Everything you need to know about time zones, daylight saving time, and handling dates across the world.
Cron Expressions: The Complete Guide to Scheduled Jobs
Learn how to read, write, and debug cron expressions for scheduling recurring tasks.