Thread View: borland.public.jbuilder.java.language
4 messages
4 total messages
Started by Petar Popara
Thu, 01 Dec 2005 17:56
java.sql.Date (homework)
Author: Petar Popara
Date: Thu, 01 Dec 2005 17:56
Date: Thu, 01 Dec 2005 17:56
18 lines
1406 bytes
1406 bytes
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: java.sql.Date (homework)
Author: Kevin Dean [TeamB]
Date: Thu, 01 Dec 2005 17:51
Date: Thu, 01 Dec 2005 17:51
71 lines
3722 bytes
3722 bytes
Petar Popara wrote: >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. http://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. http://www.datadevelopment.com/ NEW WHITEPAPERS Team Development with JBuilder and Borland Enterprise Server Securing Borland Enterprise Server http://www.datadevelopment.com/papers/index.html Please see Borland's newsgroup guidelines at http://info.borland.com/newsgroups/guide.html
Re: java.sql.Date (homework)
Author: Daniel Becroft
Date: Thu, 01 Dec 2005 18:58
Date: Thu, 01 Dec 2005 18:58
50 lines
2538 bytes
2538 bytes
Petar Popara wrote:
>
> 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."
Re: java.sql.Date (homework)
Author: Petar Popara
Date: Thu, 01 Dec 2005 19:18
Date: Thu, 01 Dec 2005 19:18
2 lines
1017 bytes
1017 bytes
Thank you. :)
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads