Bug #18532 Updated: date('W'...) returns wrong weeknumbers

From: Date: Fri, 26 Jul 2002 16:51:45 +0000
Subject: Bug #18532 Updated: date('W'...) returns wrong weeknumbers
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-15361@lists.php.net to get a copy of this message
ID: 18532 Updated by: georg@php.net Reported By: tmus@get2net.dk -Status: Assigned +Status: Closed Bug Type: Date/time related Operating System: Linux / Windows XP PHP Version: 4.2.1 Assigned To: georg New Comment: This bug has been fixed in CVS. You can grab a snapshot of the CVS version at http://snaps.php.net/. In case this was a documentation problem, the fix will show up soon at http://www.php.net/manual/. In case this was a PHP.net website problem, the change will show up on the PHP.net site and on the mirror sites. Thank you for the report, and for helping us make PHP better. Previous Comments: ------------------------------------------------------------------------ [2002-07-26 04:06:15] georg@php.net Yes, you're right. Looks like the code is a little bit buggy. I'll fix that. ------------------------------------------------------------------------ [2002-07-25 11:45:49] pguillot@paanjaru.com %W returns some 0th week of the year : $deb = mktime( 0, 0, 0, 1, 1, '2002'); print 'Week test for day '. $deb ."\n"; print 'for day '. strftime( '%d-%m-%Y', $deb) ."\n"; print 'strftime %Y-%W gives '; print strftime( '%Y-%W', $deb ) . "\n"; When run, it gives Week test for day 1009839600 (01-01-2002) strftime %Y-%W gives 2002-00 So, this will lead to a lot of problems when using week computations ... you can use function D2YWeeknum( $date ) { // // pg 20020719 pguillot@paanjaru.com // for intentis.net // Inspired Algorithm used:From Klaus Tondering's Calendar document (The Authority/Guru) // http://www.tondering.dk/claus/calendar.html // // It's not yet possible in the port to select the week start. $supplemental = ""; $this_date = getdate( $date ); $year = $this_date['year']; $month = $this_date['mon']; $day = $this_date['mday']; $a = floor( ( 14 - $month ) / 12 ); $y = $year + 4800 - $a; $m = $month + 12 * $a - 3; $J = $day + floor( ( 153 * $m + 2 ) / 5 ) + 365 * $y + floor( $y / 4) - floor( $y / 100 ) + floor( $y / 400 ) - 32045; $d4 = ( ( ( $J + 31741 - ( $J % 7 ) ) % 146097) % 36524) % 1461; $L = floor( $d4 / 1460); $d1 = ( ( $d4 - $L ) % 365 ) + $L; $week = floor( $d1 / 7 ) + 1; if ( $week < 10 ) { $supplemental = '0'; } return( $year .'-'. $supplemental . $week ); } wich will gives you a correct number ... ------------------------------------------------------------------------ [2002-07-25 09:19:41] tmus@get2net.dk I made a small C function that's supposed to carry out the calculation(based on the W handling code of the php datetime.c file) Please notice that I am in no way a math wiz and that this routine is likely optimizable and maybe even buggy. However, to the depth of my tests, it seems to do the trick... I provide it here as a "it-could-be-done-something-like-this" kinda thing... I'm sorry I'm unable to write a proper patch for you to test, but I have no working compiler at the moment. Please take it for a spin if you like or use it for inspiration. Also check out the link mentioned elsewhere in the report. He has a lot of sample script etc. that may provide you with useful information... Here goes the code ----------------------------------- /********************************************************* * * tm_wday: day of week(0=sun - 6=sat) * tm_yday: day of year(0=jan 1. - 364 or 365(leap years) * tm_leap: current year leap flag(0 if not leap - 1 if leap) * ly_leap: last years leap flag(0 if not leap - 1 if leap) * *********************************************************/ int week(int tm_wday, int tm_yday, int tm_leap, int ly_leap){ int yd, fd, ld, wk, wd; wd = ( tm_wday == 0 ) ? 7 : tm_wday; yd = tm_yday + 1; fd = ( 7 + ( wd - yd ) % 7 ) % 7; ld = ( fd + ( 364 + tm_leap ) %7 ) %7; wk = ( ( yd + fd - 1 ) / 7 ) + 1; if ( fd > 3 ) wk--; if ( ld < 3 && yd > ( ( 364 + tm_leap ) - ld ) ) wk = 1; if( wk == 0 ) wk = week( tm_wday, 364+ly_leap, ly_leap, 0 ); return( wk ); } --------------------------------------------- ------------------------------------------------------------------------ [2002-07-24 14:57:12] tmus@get2net.dk I'm sorry, but did you read my bug report before closing it as bogus..? it returns Week 53 for TUESDAY 31 Dec. and Week 1 for the day AFTER that - This is incorrect!!! The way I read the ISO date specification, it is NOT possible for the same week MON-SUN to have two different week numbers!!! And the ISO specifies that a WEEK is STARTING on monday and ENDING on sunday, so howcome the weeknumber changes between Tuesday and Wednesday... Please just try the code i sent you guys! ------------------------------------------------------------------------ [2002-07-24 12:36:19] georg@php.net date uses iso8601 standard which supports long years (53 weeks). the first week of the ISO calendar year can begin as late as 4 January and as early as 29 December of the previous year. Likewise, the last week of the ISO calendar year can end as early as 28 December and as late as 3 January of the following year. ------------------------------------------------------------------------ The remainder of the comments for this report are too long. To view the rest of the comments, please view the bug report online at http://bugs.php.net/18532 -- Edit this bug report at http://bugs.php.net/?id=18532&edit=1

« previous php.bugs (#15361) next »