To: djgpp AT delorie DOT com Subject: Re: strftime: Need Help with Time Offsets References: <1a524t0tk28cmv3vqfq26tooe0qeikhgm5 AT 4ax DOT com> <2561-Fri22Dec2000120234+0200-eliz AT is DOT elta DOT co DOT il> <1190-Fri22Dec2000173248+0200-eliz AT is DOT elta DOT co DOT il> <0nt94tkh5ptfohe9414da1u3geja7ml4vm AT 4ax DOT com> <20001226124727 DOT A19514 AT kendall DOT sfbr DOT org> <419i4tsoc9dgtbp9okme2cghdn09uocgq4 AT 4ax DOT com> From: Esa A E Peuha Date: 04 Jan 2001 09:01:01 +0200 In-Reply-To: Jason Green's message of "Tue, 26 Dec 2000 23:36:05 +0000" Message-ID: <86pofxnajiq.fsf@sirppi.helsinki.fi> Lines: 73 X-Mailer: Gnus v5.6.43/Emacs 19.34 Reply-To: djgpp AT delorie DOT com Jason Green 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/