17

I am using the compareTo method in Java to try and check if a certain date is greater than or equal than 24 hours after another date.

How do I determine what integer to compare the date to?

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
Zach Sugano
  • 1,567
  • 5
  • 22
  • 41
  • 5
    Can you clarify? Do you mean 24 hours, one calendar day, or do you mean "adjacent 24 hour segments"? – cheeken Jun 21 '12 at 21:01
  • 1
    I don't want to check if it is the next day, I want to check if it is exactly 24 hours later or greater. – Zach Sugano Jun 21 '12 at 21:02
  • what en you think of GregorianCalendar class? – 11684 Jun 21 '12 at 21:03
  • Why can't I just compare the dates using the compareTo method? – Zach Sugano Jun 21 '12 at 21:05
  • whatever you do, you will need to consider whether timezones and/or daylight savings time (DST) come into the equation. In other words, do you want it to measure exactly 24 hours of elapsed GMT (rather UTC), or 24 hours difference between the wall clock time on clock instance 1 and clock instance 2? – Kevin Welker Jun 21 '12 at 21:06
  • 3
    The `compareTo` method only tells you whether one `Date` is before or after another. It doesn't tell you how much of a difference there is. To see if `Date a` is at least 24 hours more than `Date b`, you need to add 24 hours to `b` and then you can call `compareTo`. A `Calendar` object is better suited for this. – Ted Hopp Jun 21 '12 at 21:10
  • Yep are these two dates are in same time zone? – ironwood Jun 22 '12 at 00:25

6 Answers6

15

Use the Calendar class. If you already have a Date object, you can still use Calendar:

Date aDate = . . .
Calendar today = Calendar.getInstance();
today.setTime(aDate);
Calendar tomorrow = Calendar.getInstance();
tomorrow.setTime(aDate);
tomorrow.add(Calendar.DAY, 1);
Date tomorrowDate = tomorrow.getTime(); // if you need a Date object
Ted Hopp
  • 232,168
  • 48
  • 399
  • 521
  • 2
    you offer to use the calendar and show how to convert from date to calendar, but how can I check if one calendar is after the other? that remains unsolved. I need to check if a calendar is from today or from a previous day, so if you can answer that too it would be nice. –  Jan 25 '13 at 09:50
  • 1
    @YekhezkelYovel - That's trivial. `Calendar` implement `Comparable`, so you can tell which calendar is after the other using `cal1.compareTo(cal2)`. It will be negative if `cal1` represents a time before `cal2`, positive if it comes after, and 0 if they are the same time. – Ted Hopp Jan 25 '13 at 16:06
  • 2
    trivial or not, that is what Zach Sugano asked so you should have included that in your answer. About checking if one date is from a previouse day (excluding comparison) I found this post http://stackoverflow.com/questions/2517709/java-comparing-two-dates-to-see-if-they-are-in-the-same-day useful. –  Jan 26 '13 at 10:11
  • @YekhezkelYovel - OP already knew about `compareTo`. The question was how to find the value to use, and that's what I answered. Note that the accepted answer also had nothing about using `compareTo`. – Ted Hopp Jan 26 '13 at 23:29
  • 1
    what I'm saying is your answer doesn't answer the OP's question. The OP already knows your answer, and you only want to make a suggestion? okay, why not make a comment? that's all I'm saying. After all, the accepted answer does tell how to compare (even if not using the .compareTo()) method), and I guess that's why it was accepted :) –  Jan 27 '13 at 08:54
  • @YekhezkelYovel - OP didn't know what was in my answer; OP knew about `compareTo`, which is what you suggested is missing from my answer. Read the question again--it was how to obtain a date that is one day later than a given date. – Ted Hopp Jan 27 '13 at 15:09
  • I never said compareTo is missing from your answer. I believe you misinterpreted my comments, but it isn't that important. You are welcomed to disregard everything I've said. –  Jan 27 '13 at 15:27
  • Actually, the way to create a new instance of calendar is: `Calendar.getInstance()` – Cacho Santa Jul 10 '13 at 23:06
  • @cacho - Good catch. The `Calendar` constructors are protected, so my code wasn't going to work. – Ted Hopp Jul 11 '13 at 00:25
13

Answer depends on what you want to achieve.

One way, could be checking difference in milliseconds. 24 h in milliseconds can be calculated via

24  *  60  *  60  *  1000   =  86400000
h      min    sec    millis  

(in code you can also write TimeUnit.HOURS.toMillis(24) which IMO is more readable)

So now you can just check if difference between two dates (expressed in milliseconds) is greater than 86400000.

Pshemo
  • 122,468
  • 25
  • 185
  • 269
  • 3
    Just remember to do everything with `long` arithmetic, not `int`. – Ted Hopp Jun 21 '12 at 21:07
  • If you are going to use units, please use them correctly. Right now, the units you have is in t^5 –  Jul 11 '13 at 00:35
  • 1
    @DaftPunk What do you mean by incorrect usage? `86400000` is in `int` range. Also there shouldn't be problem with comparing `long` with `int` like `someLong1 - someLong2 > someInt`. – Pshemo Jul 11 '13 at 02:03
  • @Pshemo units... you have your units in days*hours*minutes*seconds*milliseconds. –  Jul 11 '13 at 02:04
  • @DaftPunk sorry its 4 a.m. where I leave and I am almost sleeping so could you be more specific? I used `h`, `min` and so on only to show what numbers before them mean. I could write it as `24*60*60*1000 [milis]` but that would be less clear what every value mean. – Pshemo Jul 11 '13 at 02:12
  • 1
    This will not take day-light saving into account (which causes some days to be 23h and others 25h). – arberg Oct 23 '14 at 09:41
11

tl;dr

myUtilDate_B
    .toInstant()
    .equals( 
        myUtilDate_A.toInstant().plus( 24 , ChronoUnit.HOURS ) 
    )  // Exactly 24 hours apart.

…and…

myUtilDate_B
    .toInstant()
    .isAfter( 
        myUtilDate_A.toInstant().plus( 24 , ChronoUnit.HOURS ) 
    )  // Over 24 hours apart.

Alternatively…

Duration.between( myUtilDate_A , myUtilDate_B )
        .compareTo( Duration.ofHours( 24 ) )  
        // Returns 0 if exactly 24 hours apart, 
        //         >0 if over 24 hours apart.

java.time

You specifically asked for comparing two date-times to ask if either:

  • Is one exactly 24 hours later than another
  • Is one more than 24 hours later than another.

The compareTo method you mentioned does not do this. It is designed to merely tell if a moment is the same, later, or sooner. The method does not care about specific spans of time such as 24 hours.

You specifically stated that the date does not matter. So you want to ignore anomalies such as Daylight Saving Time (DST) that make a day longer or shorter than 24 hours.

So we can work in UTC. No need for time zones.

If you were referring to java.util.Date objects, first convert them to java.time objects. The Date class is part of the troublesome old date-time classes, along with Calendar, that are now legacy, supplanted by the java.time classes.

The equivalent of java.util.Date is java.time.Instant. The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).

You can convert to/from java.time types via new methods added to the old classes.

Instant start = myUtilDate_Start.toInstant();
Instant stop = myUtilDate_Stop.toInstant();

Define the gap we care about, in this case twenty four hours, as a Duration object.

Duration d = Duration.ofHours( 24 );  // We mean literally 24 hours, not a day.

Use that Duration to calculate the 24-hours-later value. Define the unit of hours by the ChronoUnit enum.

Instant target = start.plus( 24 , ChronoUnit.HOURS );

Lastly, compare the second date-time value. Call equals and isAfter.

Boolean isExactly24HoursLater = stop.equals( target );
Boolean isOver24HoursLater = stop.isAfter( target );

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.

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

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

Where to obtain the java.time classes?

  • Java SE 8 and SE 9 and later
    • Built-in.
    • Part of the standard Java API with a bundled implementation.
    • Java 9 adds some minor features and fixes.
  • Java SE 6 and SE 7
    • Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
  • Android

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.


Joda-Time

UPDATE: The Joda-Time project, now in maintenance mode, advises migration to the java.time classes. This section is left here intact for history.

Joda-Time makes this work easier.

DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" );
DateTime dateTimeInQuestion = new DateTime( 2014, 1, 2, 3, 4, 5, 6, timeZone );  // Or: new DateTime( someJavaDotUtilDotDateObject );
DateTime now = new DateTime( timeZone );
DateTime twentyFourHoursFromNow = now.plusHours( 24 ); // Ignores Daylight Saving Time (DST). If you want to adjust for that, call: plusDays( 1 ) instead.
DateTime isDateTimeInQuestionAfter24HoursFromNow = dateTime.isAfter( twentyFourHoursFromNow );

1 Day ≠ 24 Hours

If you really meant to consider the same wall-clock time of the next day, call plusDays( 1 ) rather than plusHours( 24 ). Joda-Time then adjusts for Daylight Saving Time (DST) or other anomalies. For example, here in the United States, that might mean 25-hours rather than 24-hours because of our 1-hour DST silliness.

Compare Within 24-Hours

If really meant to test if the date-time in question lands within that 24-hour span of time, use one of Joda-Time's three classes for spans of time: Interval, Duration, and Period.

Interval interval = new Interval( now, twentyFourHoursFromNow );
boolean isDateTimeInQuestionContainedWithinNext24Hours = interval.contains( dateTimeInQuestion );

For that kind of comparison, Joda-Time uses "Half-Open" logic. This means the beginning date-time is inclusive while the ending is exclusive. In other words, comparing for GREATER THAN OR EQUAL TO (>=) the start, but LESS THAN (<) the ending. This approach usually makes the most sense when working with date-time.

Community
  • 1
  • 1
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
2

This will help you check if your date was yesterday

public static final long ONE_MINUTE = 60 * 1000;
public static final long ONE_HOUR = 60 * ONE_MINUTE;
public static final long ONE_DAY = 24 * ONE_HOUR;

public static boolean isYesterday(Date d) {
    return DateUtils.isToday(d.getTime() + ONE_DAY);
} 
Etienne Lawlor
  • 6,817
  • 18
  • 77
  • 89
2

In your Activity OnCreate

    //Get current date - yymmdd increases only
    SimpleDateFormat formatter = new SimpleDateFormat("yyMMdd");
    Date now = new Date();
    int nowTime= Integer.parseInt(formatter.format(now));

    //Get last login date - stored in db
    int lastLogin= dbManager.getLastLoginDate();

    //Check if next day
    if(nowTime> lastLogin){

        //Do your stuff
        //Update last login date
        dbManager.saveLoginDate(nowTime);
    }
uebeL
  • 41
  • 3
1

To find the delta between dates: In short,

long endL = end.getTimeInMillis() + end.getTimeZone().getOffset( end.getTimeInMillis() ); 
long startL = this.getTimeInMillis() + this.getTimeZone().getOffset(this.getTimeInMillis());
return (endL - startL) / MILLISECS_PER_DAY;

In detail,

http://user.xmission.com/~goodhill/dates/deltaDates.html

Eternal Noob
  • 2,717
  • 5
  • 27
  • 41