Mail Archives: djgpp/2001/01/04/02:01:29
Jason Green <news AT jgreen4 DOT fsnet DOT co DOT uk> writes:
> This is what needs to be figured out:
>
> : In this system, weeks begin on a Monday and week 1 of the year is the
> : week that includes January 4th, which is also the week that includes
> : the first Thursday of the year, and is also the first week that
> : contains at least four days in the year. If the first Monday of
> : January is the 2nd, 3rd, or 4th, the preceding days are part of the
> : last week of the preceding year; thus, for Saturday 2nd January 1999,
> : %G is replaced by 1998 and %V is replaced by 53. If December 29th,
> : 30th, or 31st is a Monday, it and any following days are part of week
> : 1 of the following year. Thus, for Tuesday 30th December 1997, %G is
> : replaced by 1998 and %V is replaced by 1.
>
> The week number, %V as defined above, needs to be calculated from the
> date fields of a struct tm.
Here's (pseudo)code to compute the week number and the year that the
week belongs to (this assumes that the fields in struct tm are in valid
ranges):
if(tm_mon == 11 &&
((tm_wday == 1 && tm_mday >= 29) ||
(tm_wday == 2 && tm_mday >= 30) ||
(tm_wday == 3 && tm_mday == 31)))
{
/* day belongs to first week of next year */
year_offset = 1;
week_number = 1;
}
else if(tm_mon == 0 &&
((tm_wday == 5 && tm_mday == 1) ||
(tm_wday == 6 && tm_mday <= 2) ||
(tm_wday == 0 && tm_mday <= 3)))
{
/* day belongs to last week of previous year */
year_offset = -1;
week_number = number_of_week(tm_wday,
tm_yday + 365 + is_leap_year(tm_year));
}
else
{
/* the usual case */
year_offset = 0;
week_number = number_of_week(tm_wday, tm_yday);
}
This uses two helper functions. The leap year checking one is simple:
is_leap_year(year)
{
return (year % 4 == 0) - (year % 100 == 0) + (year % 400 == 100);
}
The other is not (this could obviously be optimized, but this way it's
hopefully rather self-explanatory):
number_of_week(wday, yday)
{
day_of_the_week_now = (wday + 6) % 7;
day_of_the_week_jan1 = (day_of_the_week_now + 53 * 7 - yday) % 7;
days_since_monday_of_first_week = yday + day_of_the_week_jan1
- 7 * (day_of_the_week_jan1 >= 4);
return days_since_monday_of_first_week / 7 + 1;
}
I hope this is of some use to you.
--
Esa Peuha
student of mathematics at the University of Helsinki
http://www.helsinki.fi/~peuha/
- Raw text -