calculate age from date

2»

• yes it would -- but the problem is that standard time functions in MS-Windows can't be used for years before 1 Jan 1970. So if you were born on 31 Dec 1969 those functions will fail.
• [b][red]This message was edited by Ed Hall at 2005-8-26 6:28:31[/red][/b][hr]
: yes it would -- but the problem is that standard time functions in MS-Windows can't be used for years before 1 Jan 1970. So if you were born on 31 Dec 1969 those functions will fail.
:
[blue]Did you try it, or look at it, or did you just glance and assume?;-)

I think you'd find that it works for a little further than your assumption. I tried it back into the 1800's... (Not too many will admit to being older.)

If you look close, all the questionable time.h functions are limited to occurring after 31 Dec 69. Anything older is mathematically calculated.

I don't think it will work prior to the change to the Gregorian system in the 1500's and it would probably add a leap day erroneously for the 1800, 1700, [red]1600[/red] years, but those catches could be added if necessary.

[red]oops, 1600 would have had a leap day...[/red]

Take Care,
Ed[/blue]

• no, I didn't try it -- I saw the time functions and ASSUMED (wrongly) it wouldn't work. My apolologies.

• : : long MJDN(date dt)
: : // Returns number of days passed since Jan. 1, 401
: : { int k, DOY, ly;
: :
: : ly = !(dt.year % 400) ||(!(dt.year % 4)&&(dt.year % 100));
: : if (!ly) ly += 2;
: : //ly is 1 for leap year, else 2
: : k = dt.year - 401;
: : DOY = (275*dt.month)/9 -ly*((dt.month+9)/12)+dt.day - 30;
: : // DOY is "day of year".
: : return (365*k + k/4 -k/100 +k/400 +DOY -1);
: : }
:
:
: Without paying much attention to if the algorithm itself is correct or not: Either use double or multiply the ints to something larger before you divide, or you will get a very inaccurate algorithm.
:

• : : : long MJDN(date dt)
: : : // Returns number of days passed since Jan. 1, 401
: : : { int k, DOY, ly;
: : :
: : : ly = !(dt.year % 400) ||(!(dt.year % 4)&&(dt.year % 100));
: : : if (!ly) ly += 2;
: : : //ly is 1 for leap year, else 2
: : : k = dt.year - 401;
: : : DOY = (275*dt.month)/9 -ly*((dt.month+9)/12)+dt.day - 30;
: : : // DOY is "day of year".
: : : return (365*k + k/4 -k/100 +k/400 +DOY -1);
: : : }
: :
: :
: : Without paying much attention to if the algorithm itself is correct or not: Either use double or multiply the ints to something larger before you divide, or you will get a very inaccurate algorithm.
: :
:
:
I guess I've become spoiled. My original version of this program uses long rather than int. That's because I wrote it with ancient turbo c compiler. (You wouldn't believe how old I am.) With a more modern compiler, such as Borland bcc32, int can handle 9 or ten digit numbers (or maybe more.) Since the MJDN of 1/1/3000 is 949,265 it's quite safe to use this program to that date and way beyond. You're right in saying that this program would fail if it were compiled with turbo c.
• : : : : long MJDN(date dt)
: : : : // Returns number of days passed since Jan. 1, 401
: : : : { int k, DOY, ly;
: : : :
: : : : ly = !(dt.year % 400) ||(!(dt.year % 4)&&(dt.year % 100));
: : : : if (!ly) ly += 2;
: : : : //ly is 1 for leap year, else 2
: : : : k = dt.year - 401;
: : : : DOY = (275*dt.month)/9 -ly*((dt.month+9)/12)+dt.day - 30;
: : : : // DOY is "day of year".
: : : : return (365*k + k/4 -k/100 +k/400 +DOY -1);
: : : : }
: : :
: : :
: : : Without paying much attention to if the algorithm itself is correct or not: Either use double or multiply the ints to something larger before you divide, or you will get a very inaccurate algorithm.
: : :
: :
: :
: I guess I've become spoiled. My original version of this program uses long rather than int. That's because I wrote it with ancient turbo c compiler. (You wouldn't believe how old I am.) With a more modern compiler, such as Borland bcc32, int can handle 9 or ten digit numbers (or maybe more.) Since the MJDN of 1/1/3000 is 949,265 it's quite safe to use this program to that date and way beyond. You're right in saying that this program would fail if it were compiled with turbo c.
:

That is right, but it wasn't what I tried to say. If you divide with integers the result will be truncated.
• : no, I didn't try it -- I saw the time functions and ASSUMED (wrongly) it wouldn't work. My apolologies.
:
:
No real biggie, except that I had hoped to have covered that specific issue. The issue I would really have to work at would be how to cover the missing days, and in which part of the world for the change to the current (Gregorian) calendar. That would take some study. They skipped a different number of days, at a different time, in different countries. Now there's an ineresting algorithm... Thanks for all, Stober. I appreciate all the information you so feeely provide.

Take Care,
Ed

• I haven't fully understood your entire code yet, but I don't see the adjustment for the change to the current (Gregorian) calendar which occurred in different places and different years around the world. In 1582, 11 days were lost in part of the world and as recent as 1752 a different part lost 12 days. This wouldn't effect someone's age calculation since few would admit to being that old, but 1 Jan 401 would surely be affected.

That is probably why there is a fixed day for the Julian calculation.

Take Care,
Ed

• : : : : : long MJDN(date dt)
: : : : : // Returns number of days passed since Jan. 1, 401
: : : : : { int k, DOY, ly;
: : : : :
: : : : : ly = !(dt.year % 400) ||(!(dt.year % 4)&&(dt.year % 100));
: : : : : if (!ly) ly += 2;
: : : : : //ly is 1 for leap year, else 2
: : : : : k = dt.year - 401;
: : : : : DOY = (275*dt.month)/9 -ly*((dt.month+9)/12)+dt.day - 30;
: : : : : // DOY is "day of year".
: : : : : return (365*k + k/4 -k/100 +k/400 +DOY -1);
: : : : : }
: : : :
: : : :
: : : : Without paying much attention to if the algorithm itself is correct or not: Either use double or multiply the ints to something larger before you divide, or you will get a very inaccurate algorithm.
: : : :
: : :
: : :
: : I guess I've become spoiled. My original version of this program uses long rather than int. That's because I wrote it with ancient turbo c compiler. (You wouldn't believe how old I am.) With a more modern compiler, such as Borland bcc32, int can handle 9 or ten digit numbers (or maybe more.) Since the MJDN of 1/1/3000 is 949,265 it's quite safe to use this program to that date and way beyond. You're right in saying that this program would fail if it were compiled with turbo c.
: :
:
: That is right, but it wasn't what I tried to say. If you divide with integers the result will be truncated.
:

True, but that's what makes the algorithm work! For instance, look at the term k/4 in the last line. k is the difference between the current year and 401. k/4 is the number of years which are multiples of 4. For instance, say the year in which you're interested is 1990. Then k = 1990-401 = 1589 and 1589/4 = 497 (in integer arithmetic). Then of the 1589 numbers 401, 402, 403,... 1989, 497 are multiples of 4. (If this isn't clear, try it with the years 402, 403, 404 and 405 rather than 1990).

• : I haven't fully understood your entire code yet, but I don't see the adjustment for the change to the current (Gregorian) calendar which occurred in different places and different years around the world. In 1582, 11 days were lost in part of the world and as recent as 1752 a different part lost 12 days. This wouldn't effect someone's age calculation since few would admit to being that old, but 1 Jan 401 would surely be affected.
:
: That is probably why there is a fixed day for the Julian calculation.
:
: Take Care,
: Ed
:
:This algorithm assumes the date is the Gregorian date. (The word "Julian" in "Julian day number has no connection to the Julian calendar). That is to say, the function returns the number of days passed since 1/1/401 on the Gregorian calendar (though of course, no one was using the Gregorian calendar at that time) and the input date, also assumed to be a date on the Gregorian calendar.