Next and Previous Date in Java (Tomorrow and Yesterday)

Get the next and previous date in Java with plusDays(1) and minusDays(1), plus time zones, DST, the next Monday and the next working day with LocalDate.

Next and previous dates at month end, year end and around February 29 in a leap year

The next and previous date in Java come from date.plusDays(1) and date.minusDays(1), where date is a LocalDate. Both methods handle month ends, year ends and February 29 for us and return a new LocalDate.

We need the next or previous date for “tomorrow” and “yesterday” labels, daily reports that cover the previous day, due-date checks and loops over a range of days.

The following example gets the day after and the day before February 28, 2026, and tomorrow’s date in India at a fixed moment.

LocalDate date = LocalDate.of(2026, 2, 28);
LocalDate next = date.plusDays(1);                        // 2026-03-01
LocalDate previous = date.minusDays(1);                   // 2026-02-27
Clock clock = Clock.fixed(Instant.parse("2026-10-10T20:00:00Z"), ZoneId.of("Asia/Kolkata"));
LocalDate tomorrowInIndia = LocalDate.now(clock).plusDays(1);   // 2026-10-12

Notice that 20:00 UTC on October 10 is already October 11 in India, so “tomorrow” there is October 12. After the month and year boundaries, we look at the time zone behind “today” and the daylight saving trap of adding 24 hours. The last sections find the next Monday and the next working day.

1. Next and Previous Day Across Month and Year Boundaries

The LocalDate class stores a year, a month and a day without a time or a zone, so one day is always one calendar step. The methods plusDays() and minusDays() roll over to the next month or year when needed, and they know which years are leap years.

Next and previous dates at month end, year end and around February 29 in a leap year
plusDays(1) and minusDays(1) roll over months, years and leap days without any extra code
DateplusDays(1)minusDays(1)Boundary
2026-02-282026-03-012026-02-27End of February in a common year
2028-02-282028-02-292028-02-272028 is a leap year
2028-03-012028-03-022028-02-29Previous day is the leap day
2026-12-312027-01-012026-12-30End of the year
2027-01-012027-01-022026-12-31Previous day is in the previous year

The generic plus(1, ChronoUnit.DAYS) gives the same result, which helps when the unit is a variable. For a list of all days in a range, datesUntil() returns a stream of consecutive dates, as the dates between two dates article shows.

LocalDate yearEnd = LocalDate.of(2026, 12, 31);
LocalDate newYear = yearEnd.plus(1, ChronoUnit.DAYS);          // 2027-01-01
LocalDate leapDay = LocalDate.of(2028, 3, 1).minusDays(1);     // 2028-02-29
List<LocalDate> weekend = LocalDate.of(2026, 10, 10).datesUntil(LocalDate.of(2026, 10, 12)).toList();   // [2026-10-10, 2026-10-11]

2. Tomorrow and Yesterday Depend on the Time Zone

The method LocalDate.now() without arguments uses the JVM default time zone, so a server in UTC and a user in India can disagree about which day is today. We pass the user’s ZoneId to now() when the date is shown to a person or used in a business rule.

LocalDate tomorrow = LocalDate.now(ZoneId.of("Europe/Berlin")).plusDays(1);    // tomorrow's date in Berlin
LocalDate yesterday = LocalDate.now(ZoneId.of("Europe/Berlin")).minusDays(1);  // yesterday's date in Berlin

Say a sales app runs a nightly job at 20:00 UTC that emails each store the totals for “yesterday”. For a store in Kolkata it is already 01:30 the next morning, so yesterday there is October 10, whereas a calculation in UTC gives October 9. A fixed Clock makes the job testable, because the test decides the current instant.

Instant jobRun = Instant.parse("2026-10-10T20:00:00Z");
LocalDate yesterdayUtc = LocalDate.now(Clock.fixed(jobRun, ZoneOffset.UTC)).minusDays(1);                // 2026-10-09
LocalDate yesterdayKolkata = LocalDate.now(Clock.fixed(jobRun, ZoneId.of("Asia/Kolkata"))).minusDays(1); // 2026-10-10

In production, the job receives Clock.systemUTC(), and the unit test passes Clock.fixed(). The current date and time article covers the now() methods and clocks in more depth.

3. Next Day for a Date-Time and Why 24 Hours Is Not Enough

For a LocalDateTime or a ZonedDateTime, plusDays(1) keeps the clock time and moves the date. On a ZonedDateTime, it keeps the clock time even on a daylight saving day, which is what “same time tomorrow” means.

The old approach of adding 86,400,000 milliseconds to a timestamp assumes that every day has 24 hours. In New York, March 8, 2026 had only 23 hours, so midnight plus 24 hours is 01:00 on March 9, not midnight.

ZoneId newYork = ZoneId.of("America/New_York");
ZonedDateTime midnight = ZonedDateTime.of(2026, 3, 8, 0, 0, 0, 0, newYork);
ZonedDateTime nextMidnight = midnight.plusDays(1);                               // 2026-03-09T00:00-04:00[America/New_York]
ZonedDateTime plusMillis = midnight.toInstant().plusMillis(86_400_000L).atZone(newYork);   // 2026-03-09T01:00-04:00[America/New_York]

A report that groups orders by day with the millisecond version puts the first hour of March 9 into March 8. When we only need the date, we call toLocalDate() first and add days to the LocalDate, as in section 1.

4. Next Monday, Previous Friday and the Next Working Day

Many “next” questions ask for a day of the week instead of the next calendar day. The TemporalAdjusters class has factory methods for them, and date.with(adjuster) applies one. The TemporalAdjusters article lists all of them.

  • The adjuster next(DayOfWeek.MONDAY) returns the first Monday after the date, never the date itself.
  • The adjuster nextOrSame(DayOfWeek.MONDAY) returns the date itself when it is already a Monday.
  • The adjusters previous(DayOfWeek.FRIDAY) and previousOrSame(DayOfWeek.FRIDAY) go back in the same way.
LocalDate saturday = LocalDate.of(2026, 10, 10);
LocalDate nextMonday = saturday.with(TemporalAdjusters.next(DayOfWeek.MONDAY));          // 2026-10-12
LocalDate lastFriday = saturday.with(TemporalAdjusters.previous(DayOfWeek.FRIDAY));      // 2026-10-09
LocalDate sameDay = saturday.with(TemporalAdjusters.nextOrSame(DayOfWeek.SATURDAY));    // 2026-10-10

For the next working day, we write our own adjuster that skips Saturday and Sunday. The method returns a lambda, because TemporalAdjuster is a functional interface, and the adjuster works on LocalDateTime too, since temporal.with(day) keeps the time.

static TemporalAdjuster nextWorkingDay() {
    return temporal -> {
        LocalDate day = LocalDate.from(temporal).plusDays(1);
        while (day.getDayOfWeek() == DayOfWeek.SATURDAY || day.getDayOfWeek() == DayOfWeek.SUNDAY) {
            day = day.plusDays(1);
        }
        return temporal.with(day);
    };
}
LocalDate friday = LocalDate.of(2026, 10, 9);
LocalDate afterFriday = friday.with(nextWorkingDay());                 // 2026-10-12
LocalDate afterTuesday = LocalDate.of(2026, 10, 13).with(nextWorkingDay());  // 2026-10-14

Public holidays need a holiday list as well. The business days article extends the same loop with a Set of holidays.

5. Next and Previous Date for a java.util.Date

A java.util.Date from an old API is an instant, not a calendar date. We convert it to a LocalDate in an explicit zone, step one day, and convert back only if the old API needs a Date again.

Date legacy = Date.from(Instant.parse("2026-03-07T23:30:00Z"));
ZoneId zone = ZoneId.of("America/New_York");
LocalDate legacyDay = legacy.toInstant().atZone(zone).toLocalDate();     // 2026-03-07
LocalDate legacyNext = legacyDay.plusDays(1);                            // 2026-03-08
Date nextAsDate = Date.from(legacyNext.atStartOfDay(zone).toInstant());
Instant nextStart = nextAsDate.toInstant();                              // 2026-03-08T05:00:00Z

We avoid new Date(date.getTime() + 24 * 60 * 60 * 1000) for the same reason as in section 3. It adds 24 hours, which is not one day on the two daylight saving days of the year.

6. Next and Previous Date in Java FAQs

Searches for the next date in Java often continue with these questions.

6.1. How do we get tomorrow’s date in Java?

We call LocalDate.now(zone).plusDays(1) with the zone of the user, for example ZoneId.of(“Europe/Berlin”). The result is a LocalDate such as 2026-10-11, and its toString() already uses the ISO format yyyy-MM-dd.

6.2. How do we check whether a date is yesterday?

We compare it with isEqual() against today minus one day.

LocalDate today = LocalDate.of(2026, 10, 10);
LocalDate orderDay = LocalDate.of(2026, 10, 9);
boolean isYesterday = orderDay.isEqual(today.minusDays(1));    // true

6.3. How do we print the next date in another format?

We format the result with a DateTimeFormatter, for example DateTimeFormatter.ofPattern(“dd/MM/yyyy”) gives 01/03/2026 for 2026-03-01. The LocalDate format article covers the patterns.

6.4. What is the previous date of January 1?

December 31 of the previous year. The call LocalDate.of(2027, 1, 1).minusDays(1) returns 2026-12-31, so no special code for the year change is needed.

7. Conclusion

The next and previous dates are plusDays(1) and minusDays(1) on a LocalDate, and both handle month ends, year ends and leap days. For “today”, “tomorrow” and “yesterday”, we pass a ZoneId or a Clock so the result does not depend on the server’s default zone.

On date-times, plusDays(1) keeps the clock time, whereas adding 24 hours of milliseconds drifts on daylight saving days. For named days, TemporalAdjusters and a small custom adjuster find the next Monday or the next working day. Further date arithmetic examples are collected in the Java date and time guide.

8. References

Happy Learning !!

Source Code on Github

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.