0

I have a piece of code that is used to calculate the number of days between two Date objects, and in most instances, it works fine. However, if the date range between the two objects includes the end of March, the result is always 1 less than it should be. e.g March 31 2014 - March 29 2014 = 1, whereas it should be 2.

I understand that this is due to the fact that March has 30 days of 24 hours and 1 day of 23 hours due to DST, which is the cause of the value being 1 less.

However, I am not sure the best way to account for the missing hour.

   // This was what I have initially
    int numDays = (int) ((dateTo.getTime() - dateFrom.getTime()) / (1000 * 60 * 60 * 24));

   // I have tried rounding, since it should have 23 hours left over, but it didn't actually work.
    int numDays = (Math.round(dateTo.getTime() - dateFrom.getTime()) / (1000 * 60 * 60 * 24));

Any help/pointers would be greatly appreciated.

I am and have to use Java 7 and I am not able to use Jodatime unfortunately.

Pectus Excavatum
  • 3,593
  • 16
  • 47
  • 68
  • 5
    If you're using Java 8, use the java.time package, not the venerable `java.util.Date`. If not, Joda Time is a recommended library. – RealSkeptic Jun 10 '15 at 16:13
  • 1
    possible duplicate of http://stackoverflow.com/questions/20165564/calculating-days-between-two-dates-with-in-java – keuleJ Jun 10 '15 at 16:25
  • 1
    Well, if you can neither use Java-8 (I delete therefore my post) nor another external library then you are really out of luck because old Java has no support for calculating durations. You have to setup your own hack as for example suggested in this [SO-post](http://stackoverflow.com/a/28865648/2491410) – Meno Hochschild Jun 10 '15 at 16:46
  • For date/time questions, especially those dealing with DST, I'd suggest you provide your locale and timezone. In the US, for example, your date range does *not* include the end of DST, so if you are in the US there must be something erroneous about your reasoning that DST is the cause. Also, you should provide code for how `dateTo` and `dateFrom` get set, as there may be something there. – dcsohl Jun 10 '15 at 17:23

1 Answers1

1

Your second example is very close. Your parentheses for Math.round() only surround the subtraction, though, so since that's already an integer (well, a long really), nothing happens, and then you divide. The other problem with your second bit of code is that you are doing integer division which always truncates the part after the decimal point. Try this:

long numDays2 = Math.round((dateTo.getTime() - dateFrom.getTime()) / (1000.0 * 60 * 60 * 24));

(As indicated, I changed the Math.round() parens, and made it floating point division by making the divisor a double.)

As indicated by the comments, though, this is a hack. In particular, it will tell you that there are two days between 6AM March 5 and 8PM March 6. It's probably not really what you want. Try this on for size instead:

    SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
    Calendar cal = Calendar.getInstance();
    cal.setTime(fmt.parse("2014-03-29"));
    long start = cal.getTimeInMillis();
    start += cal.getTimeZone().getOffset(start);
    cal.setTime(fmt.parse("2014-03-31"));
    long end = cal.getTimeInMillis();
    end += cal.getTimeZone().getOffset(end);

    System.out.println((end - start)/86400000.0);

Is it ugly? Yes. Is it weird? Yes. Does it work? Yes (I think so). Note that I'm providing a double as a result; you can apply any rounding you want to this result.

dcsohl
  • 7,186
  • 1
  • 26
  • 44