17

I am trying to compare two calendars in java to decide if one of them is >= 24 hours ago. I am unsure on the best approach to accomplish this.

// get today's date
Date today = new Date();
Calendar currentDate = Calendar.getInstance();
currentDate.setTime(today);

// get last update date
Date lastUpdate = profile.getDateLastUpdated().get(owner);
Calendar lastUpdatedCalendar = Calendar.getInstance();
lastUpdatedCalendar(lastUpdate);

// compare that last hotted was < 24 hrs ago from today?
Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
Biscuit128
  • 5,218
  • 22
  • 89
  • 149
  • Hope this might help http://stackoverflow.com/questions/1555262/calculating-the-difference-between-two-java-date-instances – Srinath Mandava Mar 15 '14 at 12:51
  • FYI, the terribly troublesome old date-time classes such as [`java.util.Date`](https://docs.oracle.com/javase/10/docs/api/java/util/Date.html), [`java.util.Calendar`](https://docs.oracle.com/javase/10/docs/api/java/util/Calendar.html), and `java.text.SimpleDateFormat` are now [legacy](https://en.wikipedia.org/wiki/Legacy_system), supplanted by the [*java.time*](https://docs.oracle.com/javase/10/docs/api/java/time/package-summary.html) classes built into Java 8 and later. See [*Tutorial* by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Feb 13 '19 at 20:57

3 Answers3

28

tl;dr

Instant now = Instant.now();
Boolean isWithinPrior24Hours = 
    ( ! yourJUDate.toInstant().isBefore( now.minus( 24 , ChronoUnit.HOURS) ) ) 
    && 
    ( yourJUDate.toInstant().isBefore( now ) 
) ;

Details

The old date-time classes (java.util.Date/.Calendar, java.text.SimpleDateFormat, etc.) have proven to be be confusing and flawed. Avoid them.

For Java 8 and later, use java.time framework built into Java. For earlier Java, add the Joda-Time framework to your project.

You can easily convert between a java.util.Date and either framework.

java.time

The java.time framework built into Java 8 and later supplants the troublesome old java.util.Date/.Calendar classes. The new classes are inspired by the highly successful Joda-Time framework, intended as its successor, similar in concept but re-architected. Defined by JSR 310. Extended by the ThreeTen-Extra project. See the Tutorial.

The Instant class represents a moment on the timeline in UTC. If you meant to ask for literally 24 hours rather than "a day", then Instant is all we need.

Instant then = yourJUDate.toInstant();
Instant now = Instant.now();
Instant twentyFourHoursEarlier = now.minus( 24 , ChronoUnit.HOURS );
// Is that moment (a) not before 24 hours ago, AND (b) before now (not in the future)?
Boolean within24Hours = ( ! then.isBefore( twentyFourHoursEarlier ) ) &&  then.isBefore( now ) ;

If you meant "a day" rather than 24 hours, then we need to consider time zone. A day is determined locally, within a time zone. Daylight Saving Time (DST) and other anomalies mean a day is not always 24 hours long.

Instant then = yourJUDate.toInstant();
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime now = ZonedDateTime.now( zoneId );
ZonedDateTime oneDayAgo = now.minusDays( 1 );
Boolean within24Hours = ( ! then.isBefore( oneDayAgo ) ) &&  then.isBefore( now ) ;

Another approach would use the Interval class found in the ThreeTen-Extra project. That class represents a pair of Instant objects. The class offers methods such as contains to perform comparisons.

Joda-Time

The Joda-Time library works in a similar fashion to java.time, having been its inspiration.

DateTime dateTime = new DateTime( yourDate ); // Convert java.util.Date to Joda-Time DateTime.
DateTime yesterday = DateTime.now().minusDays(1);
boolean isBeforeYesterday = dateTime.isBefore( yesterday );

Or, in one line:

boolean isBeforeYesterday = new DateTime( yourDate).isBefore( DateTime.now().minusDays(1) );
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
15

you could use Date.getTime(), here's an example:

public final static long MILLIS_PER_DAY = 24 * 60 * 60 * 1000L;
public static void main(String args[]) throws Exception {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    Date date1 = sdf.parse("2009-12-31");
    Date date2 = sdf.parse("2010-01-31");

    boolean moreThanDay = Math.abs(date1.getTime() - date2.getTime()) > MILLIS_PER_DAY;

    System.out.println(moreThanDay);
}
oschlueter
  • 2,596
  • 1
  • 23
  • 46
  • 1
    FYI, the terribly troublesome old date-time classes such as [`java.util.Date`](https://docs.oracle.com/javase/10/docs/api/java/util/Date.html), [`java.util.Calendar`](https://docs.oracle.com/javase/10/docs/api/java/util/Calendar.html), and `java.text.SimpleDateFormat` are now [legacy](https://en.wikipedia.org/wiki/Legacy_system), supplanted by the [*java.time*](https://docs.oracle.com/javase/10/docs/api/java/time/package-summary.html) classes built into Java 8 and later. See [*Tutorial* by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Feb 13 '19 at 20:57
0

You can check localDateTime whether its in 24 hours or not, depending on zone offset parameter like following the example.

@Test
public void checkIsWithin24Hours() {
    final ZoneOffset zoneOffset = ZoneOffset.UTC;
    
    final LocalDateTime now = LocalDateTime.now(zoneOffset);
    final LocalDateTime after = LocalDateTime.now(zoneOffset).plusHours(5);

    final long nowHours = TimeUnit.MILLISECONDS.toHours(now.toInstant(zoneOffset).toEpochMilli());
    final long afterFiveHours = TimeUnit.MILLISECONDS.toHours(after.toInstant(zoneOffset).toEpochMilli());
    
    assertThat(afterFiveHours - nowHours <= 24).isTrue();
}