How to check if a date Object equals yesterday?

Solution 1:

Calendar c1 = Calendar.getInstance(); // today
c1.add(Calendar.DAY_OF_YEAR, -1); // yesterday

Calendar c2 = Calendar.getInstance();
c2.setTime(getDateFromLine(line)); // your date

if (c1.get(Calendar.YEAR) == c2.get(Calendar.YEAR)
  && c1.get(Calendar.DAY_OF_YEAR) == c2.get(Calendar.DAY_OF_YEAR)) {

This will also work for dates like 1st of January.

Solution 2:

java.time

Using java.time framework built into Java 8

LocalDate now = LocalDate.now(); //2015-11-24
LocalDate yesterday = LocalDate.now().minusDays(1); //2015-11-23

yesterday.equals(now); //false
yesterday.equals(yesterday); //true

Official Oracle LocalDate tutorial states

The equals method should be used for comparisons.

If you're working with objects such as LocalDateTime, ZonedDateTime, or OffsetDateTime, you may convert to LocalDate.

LocalDateTime.now().toLocalDate(); # 2015-11-24

Solution 3:

I agree with Ash Kim that the Joda-Time library is the way to go if you want to preserve your sanity.

import org.joda.time.DateTime;

public static boolean dayIsYesterday(DateTime day) {
    DateTime yesterday = new DateTime().withTimeAtStartOfDay().minusDays(1);
    DateTime inputDay = day.withTimeAtStartOfDay();

    return inputDay.isEqual(yesterday);
}

In this example, if the DateTime day is from yesterday then dayIsYesterday(day) will return true.

Solution 4:

Avoid java.util.Date & .Calendar

The accepted answer is technically correct but less than optimal. The java.util.Date and .Calendar classes are notoriously troublesome. Avoid them. Use either Joda-Time or the new java.time package (in Java 8).

Time Zone

Time zone is critical in date-time work. If you ignore the issue, the JVM's default time zone will be applied. A better practice is to always specify rather than rely on default. Even when you want the default, explicitly call getDefault.

The beginning of the day is defined by the time zone. A new day dawns earlier in Berlin than in Montréal. So the definition of "today" and "yesterday" requires a time zone.

Joda-Time

Example code in Joda-Time 2.3.

DateTimeZone timeZone = DateTimeZone.forID( "Europe/Berlin" );
DateTime today = DateTime.now( timeZone ); 

One way to determine yesterday is by converting to LocalDate objects. Another way, shown here, is to represent "yesterday" as a span of time. We define that span as going from the first moment of yesterday up to but not including the first moment of today. This approach is called "half-open" where the beginning is inclusive and the ending is exclusive.

Subtract a day to get to yesterday (or day before).

DateTime yesterdayStartOfDay = today.minusDays( 1 ).withTimeAtStartOfDay();
Interval yesterdayInterval = new Interval( yesterdayStartOfDay, today.withTimeAtStartOfDay() );

Convert your target java.util.Date object to a Joda-Time DateTime object. Apply a time zone to that new object, rather than rely on applying JVM's default time zone. Technically the time zone here in this case is irrelevant, but including a time zone is a good habit.

DateTime target = new DateTime( myJUDate, timeZone );

Test if the target lands within the interval of yesterday.

boolean isYesterday = yesterdayInterval.contains( target );

Obviously this approach with half-open span of time works with more than just "yesterday", such as "this week", "last month", and so on.

Updated: The Joda-Time project is now in maintenance mode. The team advises migration to the java.time classes. See the java.time solution in the correct Answer by Przemek.


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes. Hibernate 5 & JPA 2.2 support java.time.

Where to obtain the java.time classes?

  • Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
    • Java 9 brought some minor features and fixes.
  • Java SE 6 and Java SE 7
    • Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
  • Android
    • Later versions of Android (26+) bundle implementations of the java.time classes.
    • For earlier Android (<26), a process known as API desugaring brings a subset of the java.time functionality not originally built into Android.
      • If the desugaring does not offer what you need, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above) to Android. See How to use ThreeTenABP….