• Post Reply Bookmark Topic Watch Topic
  • New Topic

Date math, this is interesting  RSS feed

 
eileen keeney
Ranch Hand
Posts: 53
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Sheriff
Posts: 22841
43
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 66
Java Linux VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.
 
Jelle Klap
Bartender
Posts: 1952
7
Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The current Java date/time API is a mess of deprecation, inconsistency and poor usability.
I'm really looking forward to JSR-310.
 
Campbell Ritchie
Marshal
Posts: 56598
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Or use Joda time.
 
Jelle Klap
Bartender
Posts: 1952
7
Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:Or use Joda time.

I do
 
eileen keeney
Ranch Hand
Posts: 53
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 3090
14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!