0

I have a Java problem where I need to check if an item has expired. This is supposed to check if the item is at least x (x is an integer and can be set to any integer value) months old.

Just to reclarify Supposing I have a pack of eggs, I want to check if it has been 1 months since I added them (dateAdded).

I wrote a simple comparison but it doesn't seem to give the correct response. Here is the code.

public Boolean isEndOfLine() {
    Calendar today = Calendar.getInstance();
    if(today.compareTo(dateAdded) >= END_OF_LINE) {
        return true;
    } else {
        return false;
    }
}

The value of end of line is an integer 12 i.e 12 months.

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
prog_24
  • 771
  • 1
  • 12
  • 26
  • 1
    can be simplified: return today.compareTo(dateAdded) >= END_OF_LINE; – Adam Jan 08 '14 at 12:47
  • 2
    http://www.joda.org/joda-time/ - A nice library for dealing with dates and times in Java. Better than using Calendar and Date. http://stackoverflow.com/questions/13764106/comparing-two-dates-using-joda-time – Ben Dale Jan 08 '14 at 12:48
  • what is END_OF_LINE? compareTo returns -1, 0 or 1... – Adam Jan 08 '14 at 12:49
  • 1
    You must first specify what you actually want to check. "Older than x months" is a colloquial condition, which cannot be expressed precisely in any programming language. Do you consider a month to be 28, 29, 30 or 31 days? Do you want to consider the time of day? If so, do you have to consider time zone changes like DST? – jarnbjo Jan 08 '14 at 12:52
  • END_OF_LINE is an integer specifying how many months back to compare to – prog_24 Jan 08 '14 at 12:52
  • @BenjaminDale: What exact advantage would Joda bring when solving this particular problem? – jarnbjo Jan 08 '14 at 12:58
  • @jarnbjo I guess in this case, it's not necessary, but I thought i'd make OP aware of such a library if they didn't already know. It's helpful and has many built in methods for this type of thing. – Ben Dale Jan 08 '14 at 13:03
  • @BenjaminDale: Sure, you can use Joda to compare dates, just as you can use the standard API to compare dates. What's the advantage of Joda when solving exactly this problem? – jarnbjo Jan 08 '14 at 13:05
  • Did you read the first sentence of my response? "I guess in this case, it's not necessary, but I thought i'd make OP aware of such a library if they didn't already know." There's absolutely 100% nothing wrong with using the standard API. – Ben Dale Jan 08 '14 at 13:08
  • @Andrew Thompson Doesn't give the correct response. I cannot use the Date Class only the GregorianCalendar class. – prog_24 Jan 08 '14 at 13:09
  • What about using LWUIT in this code to make the comparison? – PHPFan Jan 08 '14 at 13:09

5 Answers5

2

I do not hold javadoc in my head, but along the lines of:

dateAdded.add(Calendar.Month, END_OF_LINE).compareTo(today) > 0
Oleg Sklyar
  • 9,834
  • 6
  • 39
  • 62
  • My upvote because this considers the OPs statement/comment about END_OF_LINE as integer tracking the past months although I am not quite sure if END_OF_LINE should be added to today instead. But the question is not very clear. And note, compareTo() is here only an instant comparison so this is okay for the specific problem. – Meno Hochschild Jan 08 '14 at 13:03
1

Here's some similar example code, but using the Joda-Time 2.3 library.

FYI:

  • A Joda-Time DateTime instance knows its own time zone.
  • The minusMonths method is smart, handles Daylight Saving Time and other issues. You may want to read its source code to verify its logic follows your business rules as to what "x number of months ago" means.
// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
// import org.joda.time.*;
// import org.joda.time.format.*;

// Better to specify a time zone explicitly rather than rely on default.
// Time Zone list… http://joda-time.sourceforge.net/timezones.html  (not quite up-to-date, read page for details)
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" );

int countMonths = 2;

DateTime now = new DateTime( timeZone );
// If you want to include the entire day, get first moment of the day by calling "withTimeAtStartOfDay".
DateTime someMonthsAgo = now.minusMonths( countMonths ).withTimeAtStartOfDay();
DateTime dateAdded = new DateTime( 2013, 5, 6, 7, 8, 9, timeZone  ); // Arbitrary values for example.

// If 'dateAdded' happened prior to our target date-time 'someMonthsAgo', the pack of eggs is expired.
Boolean isEndOfLine = dateAdded.isBefore( someMonthsAgo );

Dump to console…

System.out.println( "now: " + now );
System.out.println( "someMonthsAgo: " + someMonthsAgo );
System.out.println( "dateAdded: " + dateAdded );
System.out.println( "isEndOfLine: " + isEndOfLine );

When run…

now: 2014-01-08T21:36:11.179+01:00
someMonthsAgo: 2013-11-08T00:00:00.000+01:00
dateAdded: 2013-05-06T07:08:09.000+02:00
isEndOfLine: true
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
0

as mentioned in the Calendar docs You should not rely on the number returned by compareTo - you just know that if it is greater than 0 that the original date is greater.

So create a new date (x months in the passed) and compare to that one.

Saad Attieh
  • 1,396
  • 3
  • 21
  • 42
0

The method returns 0 if the time represented by the argument is equal to the time represented by this Calendar object; or a value less than 0 if the time of this Calendar is before the time represented by the argument; or a value greater than 0 if the time of this Calendar is after the time represented.

    import java.util.*;

    public class CalendarDemo {

       public static void main(String[] args) {

          // create two calendar at the different dates
          Calendar cal1 = new GregorianCalendar(2015, 8, 15);
          Calendar cal2 = new GregorianCalendar(2008, 1, 02);

          // compare the time values represented by two calendar objects.
          int i = cal1.compareTo(cal2);

          // return positive value if equals else return negative value
          System.out.println("The result is :"+i);

          // compare again but with the two calendars swapped
          int j = cal2.compareTo(cal);

          // return positive value if equals else return negative value
          System.out.println("The result is :" + j);

       }
    }
Lijo
  • 6,498
  • 5
  • 49
  • 60
0

Here is the working solution. Tested with JUNIT to confirm results.

public Boolean isEndOfLine() {
    Calendar today = Calendar.getInstance();
    today.add(Calendar.MONTH, -END_OF_LINE);
    return today.compareTo(dateAdded) >= 0;
}

I subtracted the END_OF_LINE from today using the add method. Notice the minus on line 3. I then compared to see if it is greater than 0. Thanks for all your suggestions.

prog_24
  • 771
  • 1
  • 12
  • 26