41

My heart is bleeding internally after having to go so deep to subtract two dates to calculate the span in number of days:

    GregorianCalendar c1 = new GregorianCalendar();
    GregorianCalendar c2 = new GregorianCalendar();
    c1.set(2000, 1, 1);
    c2.set(2010,1, 1);
    long span = c2.getTimeInMillis() - c1.getTimeInMillis();
    GregorianCalendar c3 = new GregorianCalendar();
    c3.setTimeInMillis(span);
    long numberOfMSInADay = 1000*60*60*24;
    System.out.println(c3.getTimeInMillis() / numberOfMSInADay); //3653

where it's only 2 lines of code in .NET, or any modern language you name.

Is this atrocious of java? Or is there a hidden method I should know?

Instead of using GregorianCalendar, is it okay to use Date class in util? If so, should I watch out for subtle things like the year 1970?

Thanks

Haoest
  • 13,610
  • 29
  • 89
  • 105

5 Answers5

49

It's indeed one of the biggest epic failures in the standard Java API. Have a bit of patience, then you'll get your solution in flavor of the new Date and Time API specified by JSR 310 / ThreeTen which is (most likely) going to be included in the upcoming Java 8.

Until then, you can get away with JodaTime.

DateTime dt1 = new DateTime(2000, 1, 1, 0, 0, 0, 0);
DateTime dt2 = new DateTime(2010, 1, 1, 0, 0, 0, 0);
int days = Days.daysBetween(dt1, dt2).getDays();

Its creator, Stephen Colebourne, is by the way the guy behind JSR 310, so it'll look much similar.

JodaStephen
  • 60,927
  • 15
  • 95
  • 117
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • 3
    I have a small project and need it in only a few places. Coming anew from .NET, I am just a bit infuriated and frustrated at java. Thanks for the confirmation, though. – Haoest Aug 19 '10 at 22:10
  • 1
    You could also create an utility method and hide it far away in the depths of your code so that you won't be directly bothered by the ugly Calendar API ;) – BalusC Aug 19 '10 at 22:35
  • Did JSR 310 ever see the day ? – James P. Aug 21 '12 at 19:41
  • 2
    @James: not in Java 7. It will likely be in Java 8, see also http://blog.joda.org/2010/12/what-about-jsr-310_153.html (note: posted 4 months after this answer). I updated the links in my answer. – BalusC Aug 21 '12 at 20:10
  • It has been implemented in Java 8 using Period.. http://www.leveluplunch.com/java/examples/number-of-days-between-two-dates/ – galactikuh Mar 01 '15 at 18:31
18

You can use the following approach:

SimpleDateFormat formater=new SimpleDateFormat("yyyy-MM-dd");

long d1=formater.parse("2001-1-1").getTime();
long d2=formater.parse("2001-1-2").getTime();

System.out.println(Math.abs((d1-d2)/(1000*60*60*24)));
daniel.deng
  • 239
  • 3
  • 3
3

If you deal with dates it is a good idea to look at the joda time library for a more sane Date manipulation model.

http://joda-time.sourceforge.net/

Peter Tillemans
  • 34,983
  • 11
  • 83
  • 114
3

Well you can remove the third calendar instance.

GregorianCalendar c1 = new GregorianCalendar();
GregorianCalendar c2 = new GregorianCalendar();
c1.set(2000, 1, 1);
c2.set(2010,1, 1);
c2.add(GregorianCalendar.MILLISECOND, -1 * c1.getTimeInMillis());
Strom
  • 356
  • 2
  • 6
  • 3
    I don't think GregorianCalendar is immutable, so if I should use c2 later again, I sort of like to have it the value as it was defined initially. – Haoest Aug 19 '10 at 22:16
0

Here's the basic approach,

DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

Date beginDate = dateFormat.parse("2013-11-29");
Date endDate = dateFormat.parse("2013-12-4");

Calendar beginCalendar = Calendar.getInstance();
beginCalendar.setTime(beginDate);

Calendar endCalendar = Calendar.getInstance();
endCalendar.setTime(endDate);

There is simple way to implement it. We can use Calendar.add method with loop. The minus days between beginDate and endDate, and the implemented code as below,

int minusDays = 0;
while (true) {
  minusDays++;

  // Day increasing by 1
  beginCalendar.add(Calendar.DAY_OF_MONTH, 1);

  if (dateFormat.format(beginCalendar.getTime()).
            equals(dateFormat.format(endCalendar).getTime())) {
    break;
  }
}
System.out.println("The subtraction between two days is " + (minusDays + 1));**
Optimus Prime
  • 6,817
  • 5
  • 32
  • 60
Luna Kong
  • 3,065
  • 25
  • 20