Mail Archives: djgpp/2001/01/09/02:00:11
On Sat, 6 Jan 2001, Jason Green wrote:
> Esa A E Peuha <peuha AT cc DOT helsinki DOT fi> wrote:
> > is_leap_year(year)
> > {
> > return (year % 4 == 0) - (year % 100 == 0) + (year % 400 == 100);
> > }
>
> This is buggy (try it for year 2000),
For year 2000, the tm_year field would be 100, and the return value
would be 1 - 1 + 1 == 1, as it should. However, for year 1600 the
argument would be -300, but -300 % 400 isn't necessarily 100 even under
C89, and C99 actually requires it to be -300 AFAIK. So this is indeed
buggy.
> > The other is not (this could obviously be optimized, but this way it's
> > hopefully rather self-explanatory):
>
> Erm, sorry, this is not obvious to me. Although that's probably more
> to do with damage suffered staring at date maths code. ;-)
No wonder. :-) It's all pretty simple once you really understand it,
but it can be mind-boggling before that. (Just be glad there's no need
to write code to compute the date of easter for a given year. ;-)
> I put your code into functions. Unfortunately, it sometimes gets the
> week number wrong where week 52/53 overlaps into the new year.
So it does. That's because I made a silly mistake (see below).
> /* day belongs to last week of previous year */
> return number_of_week (t->tm_wday,
> t->tm_yday +
> ((isleap(t->tm_year + TM_YEAR_BASE)) ?
> 366:365));
This, of course, needs to add the number of days in the previous year,
so it should test for isleap(t->tm_year + TM_YEAR_BASE - 1). BTW, why
is there an extra set of parentheses around isleap(...)?
--
Esa Peuha
student of mathematics at the University of Helsinki
http://www.helsinki.fi/~peuha/
- Raw text -