16

Is it a valid way of comparing dates:

Calendar someCalendar1 = Calendar.getInstance(); // current date/time
someCalendar1.add(Calendar.DATE, -14);

Calendar someCalendar2 = Calendar.getInstance();
someCalendar2.setTime(someDate); // someDate is in the format of MM/dd/yyyy

if(someCalendar2.compareTo(someCalendar1) < 0){
   ...Code...               
}

...or is there a better approach?

Shog9
  • 156,901
  • 35
  • 231
  • 235

5 Answers5

20

Date implements comparable itself so there's no reason to wrap it into calendar:

Calendar someCalendar1 = Calendar.getInstance(); // current date/time
someCalendar1.add(Calendar.DATE, -14);

if (someDate.compareTo(someCalendar1.getTime()) < 0) {
   ...Code...                           
}

Date also has convenient after() and before() methods that make the above comparison easier to read:

if (someDate.before(someCalendar1.getTime())) {
   ...Code...                           
}

Finally, if you're dealing with date / time a lot, do consider using Joda Time instead of built-in java classes. It's MUCH more convenient and functional:

DateTime dt = new DateTime().minusWeeks(2);
if (new DateTime(someDate).isBefore(dt)) {
   ...Code...                           
}
lagget
  • 7
  • 4
ChssPly76
  • 99,456
  • 24
  • 206
  • 195
  • If you just compare Date, don't you lose all your timezone data, and thus get the wrong answer unless both Calendars are in the same timezone? – Joe Zitzelberger Aug 09 '13 at 13:37
7

It's valid, but you're slightly confused about someDate - Calendar.setTime takes a java.util.Date, which is just a wrapper around a long indicating the number of milliseconds since midnight Jan 1st 1970, UTC. It's not "in the format MM/dd/yyy" - that's a string representation, not a java.util.Date. If it happens to print something out in the format MM/dd/yyyy, that's just what Date.toString is doing for you - it's not inherently part of the format.

As an aside, I would personally recommend that you avoid java.util.Date and java.util.Calendar completely and use Joda Time instead. It's a much better API.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Joda.org now recommends to use Java 8's time API instead of using it's own library. [Joda's new home page](http://www.joda.org/joda-time/) " Note that from Java SE 8 onwards, users are asked to migrate to java.time (JSR-310) - a core part of the JDK which replaces this project." – a_secenthusiast May 15 '16 at 14:03
  • @user917279: Yes, but I'm not going to go and find every recommendation for Joda Time between 2008 and 2014 and update them :) – Jon Skeet May 15 '16 at 15:13
  • Jon, that was not my intention. I loved this answer and went to kids website, but was surprised to read this recommendation. so thought of sharing this with people ( like me ) who may not be aware of this. apologies for not clarifying earlier. – a_secenthusiast May 15 '16 at 19:05
  • @user917279: No problem. And really, if I *could* easily update them all, I would... – Jon Skeet May 15 '16 at 19:11
2

As one example of why Joda is better, take Daylight Savings Time.

If you're measuring "one day" as 1000 * 60 * 60 * 24 milliseconds, the Date library - and the Calendar library - both forget that there's one day in the year with 25 hours, and another with 23. You will occasionally screw up date calculations if you rely solely on the Java classes built into the J2SE API.

Joda is half likely to be the drop-in replacement for GregorianCalendar, Calendar, and Date in a future version of Java.

Dean J
  • 39,360
  • 16
  • 67
  • 93
  • 1
    JSR-310 isn't exactly the same as Joda, although it's very similar due to being spear-headed by the same person. It can't arrive fast enough IMO. – Jon Skeet Oct 01 '09 at 19:04
  • JSR-310 arrived as [java.time](https://docs.oracle.com/javase/tutorial/datetime/TOC.html) in Java 8 (March 2014). Very highly recommended. – Ole V.V. Oct 27 '19 at 07:11
1

It’s an old question now. For it to be helpful to the readers of today and tomorrow it needs a modern answer. That’s what I am providing here.

java.time

    LocalDate someDate1 = LocalDate.now(ZoneId.of("Africa/Lusaka"))
            .minusDays(14);
    LocalDate someDate2 = LocalDate.of(2019, Month.OCTOBER, 11);

    if (someDate2.isBefore(someDate1)) {
        System.out.println("" + someDate2 + " is before " + someDate1);
    }

When I ran this code today, the output was:

2019-10-11 is before 2019-10-13

While it was valid to use Calendar in 2009, the class was always poorly designed and is now long outdated. I certainly recommend that no one uses it anymore. Instead use java.time, the modern Java date and time API.

Link: Oracle tutorial: Date Time explaining how to use java.time.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
0

It's OK. Also you can use before() and after():

package demo.so;

import java.util.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;

public class Tester {

    public static void main(String[] args) throws Exception {

    Calendar someCalendar1 = Calendar.getInstance(); // current date/time
    someCalendar1.add(Calendar.DATE, -11);

    DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
    Date someDate =   df.parse("10/08/2009");

    Calendar someCalendar2 = Calendar.getInstance();
    someCalendar2.setTime(someDate);

    String cal1 = df.format(someCalendar1.getTime());
    String cal2 = df.format(someCalendar2.getTime());

    if (someCalendar1.equals(someCalendar2))
        System.out.println( cal1 + " is the same as " + cal2);
    if (someCalendar1.after(someCalendar2))
        System.out.println(cal1 + " is after " + cal2);
    if (someCalendar1.before(someCalendar2))
        System.out.println(cal1 + " is before " + cal2);

    }

}

But you shouldn't use Date, is deprecated and a source of troubles with dates handling. Build your own wrapper for GregorianCalendar or use some good library, like Joda.

JuanZe
  • 8,007
  • 44
  • 58