Bug #18532 Updated: date('W'...) returns wrong weeknumbers
| From: | georg@php.net | 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