#18532 [Com]: date('W'...) returns wrong weeknumbers
| From: | tmus at get2net dot dk | Date: | Tue, 10 Sep 2002 09:54:34 +0000 |
| Subject: | #18532 [Com]: date('W'...) returns wrong weeknumbers | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-18905@lists.php.net to get a copy of this message | ||
ID: 18532
Comment by: tmus@get2net.dk
Reported By: tmus@get2net.dk
Status: Closed
Bug Type: Date/time related
Operating System: Linux / Windows XP
PHP Version: 4.2.1
Assigned To: georg
New Comment:
I was just wondering why the fix does not seem to be in the 4.2.3
release - am I incorrect or what? I have not installed it yet (prod
system) but the source code for the 'W' function does not appear to
have changed?!?
Previous Comments:
------------------------------------------------------------------------
[2002-07-26 12:51:44] georg@php.net
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.
------------------------------------------------------------------------
[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!
------------------------------------------------------------------------
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