Big Moose Saloon
 Search | Java FAQ | Recent Topics Register / Login

# Date math, this is interesting

eileen keeney
Ranch Hand

Joined: May 04, 2009
Posts: 51
public static long getDateDiff(
int yearIn,
int monthIn,
int dayIn
)
{
Calendar calToday = Calendar.getInstance();

Calendar calOther = Calendar.getInstance();

calOther.set(yearIn, (monthIn - 1), dayIn);

long dateInMiliToday = calToday.getTimeInMillis();
long dateInMiliOther = calOther.getTimeInMillis();

long diffMili = dateInMiliToday - dateInMiliOther;
long diffDays = diffMili / (24 * 60 * 60 * 1000);

return diffDays;
}

Now I test the method with the following lines of code:

long diffDays = getDateDiff( 2012, 04, 13 );
System.out.println("diff in days:" + diffDays);
diffDays = getDateDiff( 2012, 04, 21 );
System.out.println("diff in days:" + diffDays);

Output is:
diff in days:6
diff in days:-2

This is what I expect (running the code when the machine date is April 19th)
Both do the math inclusive of one end of the compare, and exclusive of one end.

If I turn around the math and instead do this:
long diffMili = dateInMiliOther - dateInMiliToday
The result is not as I would have expected.

diff in days:-5
diff in days:2

I find this really interesting.
I will have to test this early in the morning and see if I get a similar result.

Does anyone else think it is a bit lame that Calendar starts with 1 for DAY_OF_MONTH but starts with 0 for MONTH?

Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 17103

5

eileen keeney wrote:Does anyone else think it is a bit lame that Calendar starts with 1 for DAY_OF_MONTH but starts with 0 for MONTH?

Lame... yeah, I'd agree that's a good word to describe it. But like my former boss used to say all the time, "It is what it is".
Prabaharan Gopalan
Ranch Hand

Joined: Oct 16, 2009
Posts: 66

Even the first week of year starts at 1, the first week of month is 1. One reason ( and this is purely my supposition) could be these are just numbers but Months are represented as JANUARY, FEBRUARY, etc and are expected to be used as such. The numbers are indices in the background (and like any index in Java, this one starts at 0). But that doesn't stop them from having JANUARY as 1 though.

Googling doesn't make you a genius. But not Googling makes you dumber.
Jelle Klap
Bartender

Joined: Mar 10, 2008
Posts: 1524

4

The current Java date/time API is a mess of deprecation, inconsistency and poor usability.
I'm really looking forward to JSR-310.

Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 34616

13
Or use Joda time.
Jelle Klap
Bartender

Joined: Mar 10, 2008
Posts: 1524

4

Campbell Ritchie wrote:Or use Joda time.

I do
eileen keeney
Ranch Hand

Joined: May 04, 2009
Posts: 51
Paul Clapham wrote:
eileen keeney wrote:Does anyone else think it is a bit lame that Calendar starts with 1 for DAY_OF_MONTH but starts with 0 for MONTH?

Lame... yeah, I'd agree that's a good word to describe it. But like my former boss used to say all the time, "It is what it is".

My boss says that a lot as well.
I guess now that I know it is using zero, it is almost moot ( I can easily work with it ).
But I did spend almost an hour thinking that the below did not automatically assign the current date.
Calendar calToday = Calendar.getInstance();

But the +6 versus -5 (when I reverse the order of the math), is still a bit baffling.
But it does come out correct this time of the day.

If I had major date/calendar work to code I would install the Joda library, but I have what I need working for now.

Thank you
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109

6

eileen keeney wrote:
I guess now that I know it is using zero, it is almost moot ( I can easily work with it ).

I still maintain that the problem isn't that MONTH is zero-based, but rather that they published that fact and made it part of the API. If they hadn't, then the simple and correct answer would be, "Don't use the actual int values. Just use the constants by name." Unfortunately, since they published it, people can use those values, though I still think it's bad practice to do so.
Mike Simmons
Ranch Hand

Joined: Mar 05, 2008
Posts: 2916

4
eileen keeney wrote:But the +6 versus -5 (when I reverse the order of the math), is still a bit baffling.
But it does come out correct this time of the day.

I think the problem is in how you are calculating it:

The problem is that integer division truncates, rather than doing proper rounding. By which I mean, let's say you have two times that are exactly 24 hours apart. That's 86400000 milliseconds. If you divide by (24*60*60*1000), you get exactly 1 day, the expected amount. But what if your time is off by just one millisecond? That depends on whether it's greater or less by 1. If the difference is 86400001, the division results in 1, because the tiny fraction of 1/86400000 is rounded down (truncated). That seems fine But if the difference is 86599999, then your division results in 0, not 1. That's one off from what you expect. That's not so good.

Now, why would you get a difference of 1 millisecond? Note how you initialized your times:

Those are two different instances, which might have slightly different initialization times.

You might try this, immediately after creating the instances:

That will probably work most of the time. However you will still get problems when your time calculation crosses daylight savings / summer time boundaries, when there's a night with only 23 hours. Instead I would simply replace the days-difference calculation with better rounding:

It's a bit of a kludge, but it should handle most any realistic situation you might encounter.

I agree. Here's the link: http://aspose.com/file-tools

subject: Date math, this is interesting