Board index » jbuilder » Re: java.sql.Date (homework)

Re: java.sql.Date (homework)


2005-12-02 01:51:52 AM
jbuilder24
Petar Popara wrote:
Quote
I have a date of birth as:

java.sql.Date dateOfBirth = ...; // get from DB

I have java.util.Date as current time:

java.util.Date now = new java.util.Date();

I need to calculate how many years is someone old. I have tried this:

long oldnessInMillis = now.getTime() - dateOfBirth.getTime();
long oldnessInYears = (oldnessInMillis / (1000 * 60 * 60 * 24 * 365));

but I got unexpected results (bigger 21.5 times). Is it because of time
zones or I have miscalculated it?
Ah yes, fun with integers.
The problem is that the compiler, when it does the arithmetic with the
numbers you have there, does it using integers by default. That's fine
right up until it gets to the last multiplication:
1000
*60 = 60,000
*60 = 3,600,000
*24 = 86,400,000
*365 = 31,536,000,000
To you and me, that looks fine, but the compiler is working with Java
integers, which are represented in four bytes and therefore have a limited
range (-2^31 to +(2^31-1) or -2,147,483,648 to +2,147,483,647 to be
exact). When you overflow an integer like that, the compiler just wraps
around to the beginning again.
The final number actually ends up wrapping around the integer limit 7
times, with a remainder of 1,471,228,928 or 21.44 times less than the
number itself, hence your problem.
A better way to do this would be to force one of the constants to be a
long integer, which will in turn force the compiler to do the calculation
using long integers. Keep in mind that the compiler will do so only at
the point where you coerce one of the constants to a long integer, so the
arithmetic up to that point will still be done with regular integers.
The recommended modification would be:
long oldnessInYears = (oldnessInMillis / (1000L * 60 * 60 * 24 * 365));
See the link below for a good discussion of Java data types and their
limits.
java.sun.com/docs/books/tutorial/java/nutsandbolts/datatypes.html
Now, if you want the calculation to be really accurate, you need to take
leap years into consideration (every four years, except every hundred,
except every four hundred). I'll leave that as an exercise. ;-)
--
Kevin Dean [TeamB]
Dolphin Data Development Ltd.
www.datadevelopment.com/
NEW WHITEPAPERS
Team Development with JBuilder and Borland Enterprise Server
Securing Borland Enterprise Server
www.datadevelopment.com/papers/index.html
Please see Borland's newsgroup guidelines at
info.borland.com/newsgroups/guide.html
 
 

Re:Re: java.sql.Date (homework)

I have a date of birth as:
java.sql.Date dateOfBirth = ...; // get from DB
I have java.util.Date as current time:
java.util.Date now = new java.util.Date();
I need to calculate how many years is someone old. I have tried this:
long oldnessInMillis = now.getTime() - dateOfBirth.getTime();
long oldnessInYears = (oldnessInMillis / (1000 * 60 * 60 * 24 * 365));
but I got unexpected results (bigger 21.5 times). Is it because of time
zones or I have miscalculated it?
Thank you in advance. :>
 

Re:Re: java.sql.Date (homework)

Petar Popara wrote:
Quote

I have a date of birth as:

java.sql.Date dateOfBirth = ...; // get from DB

I have java.util.Date as current time:

java.util.Date now = new java.util.Date();

I need to calculate how many years is someone old. I have tried this:

long oldnessInMillis = now.getTime() - dateOfBirth.getTime();
long oldnessInYears = (oldnessInMillis / (1000 * 60 * 60 * 24 * 365));

but I got unexpected results (bigger 21.5 times). Is it because of time zones or I have
miscalculated it?

Thank you in advance. :>
Do you need to have fractions of years? If not, then I would just do something like the following:
/* **************************************************************************** */
[ Untested ]
int adjustment = 0;
if now.GetMonth() < dateOfBirth.getMonth() then
adjustment = -1;
if now.GetMonth == dateOfBirth.GetMonth() && now.GetDate() < dateOfBirth.getDate()
adjustment = -1;
/*
** If adjustment == 0, then the person has had their birthday this year, otherwise, we need to
** adjust for this.
*/
int age_in_years = now.GetYear() - dateOfBirth.GetYear() + adjustment;
/* **************************************************************************** */
This, personally, gives cleaner code. But that's just me.
--
Daniel Becroft
; =================================
"Real computer scientists don't comment their code. The identifiers are so long they can't afford
the disk space."
"Blue sparks and white smoke, the two most expensive components of any electrical system, and once
used up will cost a fortune to replace."
 

{smallsort}

Re:Re: java.sql.Date (homework)

Thank you. :)