Java 8
Date Calculation
Programming
Java Date API
Time Interval

Calculate days between two Dates in Java 8

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In Java 8, the normal way to calculate the number of days between two calendar dates is ChronoUnit.DAYS.between. The confusion usually starts when people mix LocalDate, LocalDateTime, Instant, and Period, which answer slightly different questions.

If you are comparing dates on the calendar and do not care about time-of-day, use LocalDate. That keeps the calculation simple and avoids time-zone surprises.

Use LocalDate With ChronoUnit.DAYS.between

For plain date math, this is the standard solution:

java
1import java.time.LocalDate;
2import java.time.temporal.ChronoUnit;
3
4public class Main {
5    public static void main(String[] args) {
6        LocalDate start = LocalDate.of(2024, 1, 1);
7        LocalDate end = LocalDate.of(2024, 1, 10);
8
9        long days = ChronoUnit.DAYS.between(start, end);
10        System.out.println(days);
11    }
12}

This prints 9, because the calculation is start-inclusive and end-exclusive. In other words, it counts how many day boundaries you cross to get from the first date to the second.

Understand Inclusive Versus Exclusive Counting

This is where many off-by-one mistakes come from:

  • from 2024-01-01 to 2024-01-01 is 0
  • from 2024-01-01 to 2024-01-02 is 1
  • from 2024-01-01 to 2024-01-10 is 9

If your business rule is inclusive, such as "how many calendar dates are covered," then add one intentionally:

java
long inclusiveDays = ChronoUnit.DAYS.between(start, end) + 1;

Do that only when the domain requires it. Do not add one just because the first result looked surprising.

Why Period Is Different

Period is useful, but it does not return a total day count:

java
1import java.time.LocalDate;
2import java.time.Period;
3
4LocalDate start = LocalDate.of(2024, 1, 1);
5LocalDate end = LocalDate.of(2024, 3, 5);
6
7Period period = Period.between(start, end);
8System.out.println(period.getMonths());
9System.out.println(period.getDays());

Period breaks the gap into years, months, and days. period.getDays() is only the remaining day component after months and years are separated out. It is not the same as the total number of days between the two dates.

If the question is "how many days total," ChronoUnit.DAYS.between is usually the right answer.

Converting Legacy Date Values

Older code often still uses java.util.Date. Convert those values into the Java 8 time API first:

java
1import java.time.LocalDate;
2import java.time.ZoneId;
3import java.time.temporal.ChronoUnit;
4import java.util.Date;
5
6Date oldStart = new Date();
7Date oldEnd = new Date(System.currentTimeMillis() + 3L * 24 * 60 * 60 * 1000);
8
9LocalDate start = oldStart.toInstant()
10    .atZone(ZoneId.systemDefault())
11    .toLocalDate();
12
13LocalDate end = oldEnd.toInstant()
14    .atZone(ZoneId.systemDefault())
15    .toLocalDate();
16
17long days = ChronoUnit.DAYS.between(start, end);
18System.out.println(days);

This is safer than subtracting raw milliseconds because you are working at the correct calendar level.

When Time of Day Matters

If you actually care about elapsed time rather than calendar dates, LocalDate may be the wrong type. For example, the difference between 2024-01-01T23:00 and 2024-01-02T01:00 is only two hours, even though the dates differ.

In that case, use Instant, ZonedDateTime, or LocalDateTime depending on the problem. The data type should match the meaning of the calculation.

Negative Results Are Useful

If the second date is before the first, ChronoUnit.DAYS.between returns a negative value:

java
1long days = ChronoUnit.DAYS.between(
2    LocalDate.of(2024, 5, 10),
3    LocalDate.of(2024, 5, 1)
4);
5
6System.out.println(days);

That is usually a good thing because it preserves interval direction. If your use case wants absolute distance, apply Math.abs(days) explicitly.

Common Pitfalls

The most common mistake is using Period.getDays() and assuming it means "total days between these two dates." It does not.

Another frequent issue is subtracting milliseconds from legacy Date objects and forgetting that the real business question is often about calendar dates, not elapsed clock time.

Developers also trip over inclusive-versus-exclusive rules. ChronoUnit.DAYS.between is consistent, but you still have to decide whether your business rule matches that convention.

Finally, choose the time type carefully. If you are solving a calendar-date problem, use LocalDate. If you are solving an elapsed-time problem, use a type that includes time.

Summary

  • Use ChronoUnit.DAYS.between with LocalDate for calendar-date differences in Java 8.
  • Remember that the calculation is start-inclusive and end-exclusive.
  • Do not use Period.getDays() as a substitute for total day count.
  • Convert legacy Date values into the Java 8 time API before doing date math.
  • Match the time type to the real question: calendar dates versus elapsed time.

Course illustration
Course illustration

All Rights Reserved.