ID:               20382
 Updated by:       [EMAIL PROTECTED]
 Reported By:      [EMAIL PROTECTED]
-Status:           Feedback
+Status:           Open
 Bug Type:         Date/time related
 Operating System: Linux Mandrake 7.2
 PHP Version:      4.3.0-dev


Previous Comments:
------------------------------------------------------------------------

[2002-11-21 23:42:22] [EMAIL PROTECTED]

Ran the automated-date-test script on a different box, this one running
windows 2000 SP2 (previously was Mandrake Linux 7.2), using the latest
available snapshot of the 4.4.0-dev tree (was php4-win32-200211220330),
and it produced the same list of incorrect dates as in the above
comment.

------------------------------------------------------------------------

[2002-11-12 19:46:28] [EMAIL PROTECTED]

OK, I decided that was needed was some kind of automated testing, so I
wrote it:
============================================
#!/root/php4-200211122230 -q
<?php

// report any errors at all
error_reporting (E_ALL);

// pass a date, supply a strtotime modifier, and get a date back
function getDateWithModifier($date, $modifier) {
        list ($year, $month, $day) = explode ("-",$date);
        $starting_timestamp = mktime (1,1,1,$month,$day,$year);
        $timestamp_with_modifier = strtotime ($modifier,
$starting_timestamp);
        return date("Y-n-j", $timestamp_with_modifier);
}

/*
** @desc: for the specified date, will find the date for the desired
day of the 
**        week that is also in the same week. Does NOT use 'strtotime'
*/
function getDayOfTheWeekFromDate($date, $desired_day_of_week) {
        // weekdays - note special case for sundays (7, not 0), so as to treat
as end of week, not start
    $weekdays = array ("Sunday" => 7, "Monday" => 1, "Tuesday" => 2,
"Wednesday" => 3,
                            "Thursday" => 4, "Friday" => 5, "Saturday"
=> 6);

    // convert into a number
    $desired_day_of_week_number = $weekdays[$desired_day_of_week];

    // see what day we have currently
    list ($year, $month, $day) = explode ("-",$date);
    $date_day_of_week = date("w", mktime
(17,17,17,$month,$day,$year));

        $new_day = $day+(($desired_day_of_week_number-$date_day_of_week)+7) %
7;
    return date("Y-n-j", mktime (17,17,17,$month,$new_day,$year));
}


// run an automated test to compare the output of these two functions,
and complain if they differ
for ($i=1; $i<1000; $i++) {
        $date =  date("Y-n-j", mktime (17,17,17,1,$i,1999));
        $strtotime_date = getDateWithModifier($date, "Monday");
        $other_date = getDayOfTheWeekFromDate($date, "Monday");
        if ($strtotime_date != $other_date) {
                print "Discrepancy for $date - results were $strtotime_date vs
$other_date\n";
        }
}

print "PHP version: " . phpversion(). "<br>\n";

?>
============================================


Here's the output that I get:
============================================
[root@www tmp]# ./automated-date-test.php 
Discrepancy for 1999-3-23 - results were 1999-3-28 vs 1999-3-29
Discrepancy for 1999-3-24 - results were 1999-3-28 vs 1999-3-29
Discrepancy for 1999-3-25 - results were 1999-3-28 vs 1999-3-29
Discrepancy for 1999-3-26 - results were 1999-3-28 vs 1999-3-29
Discrepancy for 1999-3-27 - results were 1999-3-28 vs 1999-3-29
Discrepancy for 1999-3-28 - results were 1999-3-28 vs 1999-3-29
Discrepancy for 2000-3-21 - results were 2000-3-26 vs 2000-3-27
Discrepancy for 2000-3-22 - results were 2000-3-26 vs 2000-3-27
Discrepancy for 2000-3-23 - results were 2000-3-26 vs 2000-3-27
Discrepancy for 2000-3-24 - results were 2000-3-26 vs 2000-3-27
Discrepancy for 2000-3-25 - results were 2000-3-26 vs 2000-3-27
Discrepancy for 2000-3-26 - results were 2000-3-26 vs 2000-3-27
Discrepancy for 2001-3-20 - results were 2001-3-25 vs 2001-3-26
Discrepancy for 2001-3-21 - results were 2001-3-25 vs 2001-3-26
Discrepancy for 2001-3-22 - results were 2001-3-25 vs 2001-3-26
Discrepancy for 2001-3-23 - results were 2001-3-25 vs 2001-3-26
Discrepancy for 2001-3-24 - results were 2001-3-25 vs 2001-3-26
Discrepancy for 2001-3-25 - results were 2001-3-25 vs 2001-3-26
PHP version: 4.3.0-dev<br>
[root@www tmp]# 
============================================

In other words, the result for these 6 days of the year consistently
appears to be wrong. (I suppose I should be glad that the very first
date I choose to test this function with just by fluke happened to be
one of those 6 days, as opposed to causing mysterious problems later!)


Does anyone else get any results that appear incorrect on running this
script?

------------------------------------------------------------------------

[2002-11-12 19:25:41] [EMAIL PROTECTED]

No problem - Modified script slightly, as shown below, to use
gmmktime(), and to also print out the before and after timestamps.
Source:
=========================================
#!/root/php4-200211122230 -q
<?php

// report any errors at all
error_reporting (E_ALL);

// pass a date, supply a strtotime modifier, and get a date back
function getDateWithModifier($date, $modifier) {
        list ($year, $month, $day) = explode ("-",$date);
        $t_start = gmmktime (17,17,17,$month,$day,$year);
        $t_new   = strtotime ($modifier, $t_start);
        return "t_start: $t_start; t_new: $t_new; "
                        . date("Y-n-j", $t_new);
}

print "<hr>\n";
print "2001-3-17, goto mon: " . getDateWithModifier("2001-3-17",
"Monday") . "; should be 2001-3-19.<br>\n";
print "2001-3-18, goto mon: " . getDateWithModifier("2001-3-18",
"Monday") . "; should be 2001-3-19.<br>\n";
print "2001-3-19, goto mon: " . getDateWithModifier("2001-3-19",
"Monday") . "; should be 2001-3-19.<br>\n";
print "2001-3-20, goto mon: " . getDateWithModifier("2001-3-20",
"Monday") . "; should be 2001-3-26 ###.<br>\n";
print "2001-3-21, goto mon: " . getDateWithModifier("2001-3-21",
"Monday") . "; should be 2001-3-26 ###.<br>\n";
print "2001-3-22, goto mon: " . getDateWithModifier("2001-3-22",
"Monday") . "; should be 2001-3-26 ###.<br>\n";
print "2001-3-23, goto mon: " . getDateWithModifier("2001-3-23",
"Monday") . "; should be 2001-3-26 ###.<br>\n";
print "2001-3-24, goto mon: " . getDateWithModifier("2001-3-24",
"Monday") . "; should be 2001-3-26 ###.<br>\n";
print "2001-3-25, goto mon: " . getDateWithModifier("2001-3-25",
"Monday") . "; should be 2001-3-26 ###.<br>\n";
print "2001-3-26, goto mon: " . getDateWithModifier("2001-3-26",
"Monday") . "; should be 2001-3-26.<br>\n";
print "2001-3-27, goto mon: " . getDateWithModifier("2001-3-27",
"Monday") . " ; should be 2001-4-2.<br>\n";
print "<hr>\n";

print "PHP version: " . phpversion(). "<br>\n";

?>
=========================================

Output:
==========================================
[root@www tmp]# ./script.php 
<hr>
2001-3-17, goto mon: t_start: 984849437; t_new: 984920400; 2001-3-19;
should be 2001-3-19.<br>
2001-3-18, goto mon: t_start: 984935837; t_new: 984920400; 2001-3-19;
should be 2001-3-19.<br>
2001-3-19, goto mon: t_start: 985022237; t_new: 985525200; 2001-3-25;
should be 2001-3-19.<br>
2001-3-20, goto mon: t_start: 985108637; t_new: 985525200; 2001-3-25;
should be 2001-3-26 ###.<br>
2001-3-21, goto mon: t_start: 985195037; t_new: 985525200; 2001-3-25;
should be 2001-3-26 ###.<br>
2001-3-22, goto mon: t_start: 985281437; t_new: 985525200; 2001-3-25;
should be 2001-3-26 ###.<br>
2001-3-23, goto mon: t_start: 985367837; t_new: 985525200; 2001-3-25;
should be 2001-3-26 ###.<br>
2001-3-24, goto mon: t_start: 985454237; t_new: 985525200; 2001-3-25;
should be 2001-3-26 ###.<br>
2001-3-25, goto mon: t_start: 985540637; t_new: 985528800; 2001-3-26;
should be 2001-3-26 ###.<br>
2001-3-26, goto mon: t_start: 985627037; t_new: 986133600; 2001-4-2;
should be 2001-3-26.<br>
2001-3-27, goto mon: t_start: 985713437; t_new: 986133600; 2001-4-2 ;
should be 2001-4-2.<br>
<hr>
PHP version: 4.3.0-dev<br>
[root@www tmp]# 
==========================================

And here is the output using mktime() instead of gmmktime():
==========================================
[root@www tmp]# ./script.php 
<hr>
2001-3-17, goto mon: t_start: 984809837; t_new: 984920400; 2001-3-19;
should be 2001-3-19.<br>
2001-3-18, goto mon: t_start: 984896237; t_new: 984920400; 2001-3-19;
should be 2001-3-19.<br>
2001-3-19, goto mon: t_start: 984982637; t_new: 984920400; 2001-3-19;
should be 2001-3-19.<br>
2001-3-20, goto mon: t_start: 985069037; t_new: 985525200; 2001-3-25;
should be 2001-3-26 ###.<br>
2001-3-21, goto mon: t_start: 985155437; t_new: 985525200; 2001-3-25;
should be 2001-3-26 ###.<br>
2001-3-22, goto mon: t_start: 985241837; t_new: 985525200; 2001-3-25;
should be 2001-3-26 ###.<br>
2001-3-23, goto mon: t_start: 985328237; t_new: 985525200; 2001-3-25;
should be 2001-3-26 ###.<br>
2001-3-24, goto mon: t_start: 985414637; t_new: 985525200; 2001-3-25;
should be 2001-3-26 ###.<br>
2001-3-25, goto mon: t_start: 985504637; t_new: 985525200; 2001-3-25;
should be 2001-3-26 ###.<br>
2001-3-26, goto mon: t_start: 985591037; t_new: 985528800; 2001-3-26;
should be 2001-3-26.<br>
2001-3-27, goto mon: t_start: 985677437; t_new: 986133600; 2001-4-2 ;
should be 2001-4-2.<br>
<hr>
PHP version: 4.3.0-dev<br>
[root@www tmp]# 
==========================================

------------------------------------------------------------------------

[2002-11-12 18:46:02] [EMAIL PROTECTED]

Hmm..could you try changing that mktime() to gmmktime() ?
And also add output of the gm/mktime() only to see what 
you get as timestamp.


------------------------------------------------------------------------

[2002-11-12 18:10:27] [EMAIL PROTECTED]

Happy to comply. I tried it with the CVS snapshot (php4-200211122230),
output was:
=============================================================
[root@www tmp]# ./script.php 
<hr>
from 2001-3-17, goto monday: 2001-3-19; should be 2001-3-19.<br>
from 2001-3-18, goto monday: 2001-3-19; should be 2001-3-19.<br>
from 2001-3-19, goto monday: 2001-3-19; should be 2001-3-19.<br>
from 2001-3-20, goto monday: 2001-3-25; should be 2001-3-26 ###.<br>
from 2001-3-21, goto monday: 2001-3-25; should be 2001-3-26 ###.<br>
from 2001-3-22, goto monday: 2001-3-25; should be 2001-3-26 ###.<br>
from 2001-3-23, goto monday: 2001-3-25; should be 2001-3-26 ###.<br>
from 2001-3-24, goto monday: 2001-3-25; should be 2001-3-26 ###.<br>
from 2001-3-25, goto monday: 2001-3-25; should be 2001-3-26 ###.<br>
from 2001-3-26, goto monday: 2001-3-26; should be 2001-3-26.<br>
from 2001-3-27, goto monday: 2001-4-2 ; should be 2001-4-2.<br>
<hr>
PHP version: 4.3.0-dev<br>
[root@www tmp]# 
=============================================================

i.e. same problem. The location of the php command-line executable
appears to have changed to 'sapi/cli/php' (in the PHP 4.2.3 build
process the executable just ends up in the root of the source
directory), so this was what I used, hope this is OK.

Here is some more info related to the problem that may or may not be
relevant:

* This machine and I are located in Sydney, Australia. The machine's
timezone as shown in 'timeconfig' is set of "Australia/Sydney", and
"Hardware clock set to GMT" is shown turned off. Output of the 'date'
command looks like this: "Wed Nov 13 10:40:22 EST 2002". Sydney is
(depending on daylight savings) around GMT + 10 hours.

* I've found today that there was a daylight savings transition for
this timezone in that week. From:
http://www.dstc.qut.edu.au/DST/marg/daylight.html - "[Daylight savings]
ends at 3am on Sunday 25 March 2001. Clocks should be turned back one
hour to read 2am (Australian Eastern Standard Time)." 

* Since there was a daylight savings transition, I've now tried various
parameters to the 'mktime' line, in case the hour/minute/second
parameters chosen were causing problems because they were too close to
the time transition. I've tried the following parameters, all of which
produce the same incorrect result:
 - mktime (23,23,23,$month,$day,$year);
 - mktime (15,15,15,$month,$day,$year);
 - mktime (10,10,10,$month,$day,$year);
 - mktime (5,5,5,$month,$day,$year);
 - mktime (1,1,1,$month,$day,$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/20382

-- 
Edit this bug report at http://bugs.php.net/?id=20382&edit=1

Reply via email to