|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2002-11-12 02:11 UTC] nickj-phpbugs at nickj dot org
Strtotime() appears to produce incorrect output under some circumstances - specifically when wanting the date of a particular day of the week day of the week from a given starting date. For example, using 2001-3-20 as a starting point, we want the date for the next Monday. The correct answer is the 26th, but the result produced is the 25th (a Sunday). The correct result is given sometimes, so this appears to depend on the input.
A sample script to illustrate:
=======================================================
#!/root/php-4.2.3 -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 (10,10,10,$month,$day,$year);
$timestamp_with_modifier = strtotime ($modifier, $starting_timestamp);
return date("Y-n-j", $timestamp_with_modifier);
}
print "<hr>\n";
print "from 2001-3-17, goto monday: " . getDateWithModifier("2001-3-17", "Monday") . "; should be 2001-3-19.<br>\n";
print "from 2001-3-18, goto monday: " . getDateWithModifier("2001-3-18", "Monday") . "; should be 2001-3-19.<br>\n";
print "from 2001-3-19, goto monday: " . getDateWithModifier("2001-3-19", "Monday") . "; should be 2001-3-19.<br>\n";
print "from 2001-3-20, goto monday: " . getDateWithModifier("2001-3-20", "Monday") . "; should be 2001-3-26 ###.<br>\n";
print "from 2001-3-21, goto monday: " . getDateWithModifier("2001-3-21", "Monday") . "; should be 2001-3-26 ###.<br>\n";
print "from 2001-3-22, goto monday: " . getDateWithModifier("2001-3-22", "Monday") . "; should be 2001-3-26 ###.<br>\n";
print "from 2001-3-23, goto monday: " . getDateWithModifier("2001-3-23", "Monday") . "; should be 2001-3-26 ###.<br>\n";
print "from 2001-3-24, goto monday: " . getDateWithModifier("2001-3-24", "Monday") . "; should be 2001-3-26 ###.<br>\n";
print "from 2001-3-25, goto monday: " . getDateWithModifier("2001-3-25", "Monday") . "; should be 2001-3-26 ###.<br>\n";
print "from 2001-3-26, goto monday: " . getDateWithModifier("2001-3-26", "Monday") . "; should be 2001-3-26.<br>\n";
print "from 2001-3-27, goto monday: " . getDateWithModifier("2001-3-27", "Monday") . " ; should be 2001-4-2.<br>\n";
print "<hr>\n";
print "PHP version: " . phpversion(). "<br>\n";
?>
=======================================================
Produces this output:
=======================================================
[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.2.3<br>
[root@www tmp]#
========================================================
Expected output: The 6 lines with "###" are expected to produce the indicated output, but do not.
Problem was noticed today in PHP 4.06, and then verified as being reproducible in PHP 4.2.3 (same output).
PHP 4.2.3 configured with:
./configure --with-mysql --enable-xml --enable-wddx
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Thu Oct 30 22:00:01 2025 UTC |
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?How's this for a short and simple test script? Applies strtotime() to every day between 1970 and 2037, and gives a list of everything that looks wrong. ====================================================== <?php $request_day = "Monday"; for ($i=1; ; $i++) { // start at year 1970, bail out at year 2038 $tStamp = mktime (17,17,17,1,$i,1970); if (date("Y", $tStamp) == 2038) break; // request a day, check what we got, complain if differs $strtotime_timestamp = strtotime ($request_day, $tStamp); $result_day = date("l", $strtotime_timestamp); if ($result_day != $request_day) print "strtotime wrong on: " . date("j-M-Y", $tStamp) . " - gave a $result_day, not a $request_day.\n"; } ?>This one shows it better: <?php putenv("TZ=Europe/Amsterdam"); $tStamp = mktime (17, 17, 17, 10, 27, 2004); echo "tStamp=". date("l Y-m-d H:i:s T", $tStamp). "\n"; $strtotime_timestamp = strtotime ("Monday", $tStamp); echo "result=". date("l Y-m-d H:i:s T", $strtotime_timestamp). "\n"; echo "wanted=Monday 2004-11-01 00:00:00 CET\n"; ?>How's this? <?php $day=date("w",strtotime("this monday")); echo $day; ?> Outputs: 1 <?php $day=date("w",strtotime("next monday")); echo $day; ?> Outputs: 0 I was going to submit a seperate bug but this definately looks related even though this is a totally different way of going about getting the same type of problem. (I knew Mondays were a little odd, but does strtotime seem to think the sunday of the next week has an extra second after midnight? As this example demonstrates it doesn't do it if you prefix the weekday with "this", just "next" or no prefix at all.)Reopening, as the original test case is now working correctly (thank you!), but there are others that don't appear to be producing the expected results. The ones that don't work seem to differ between operating systems. For Linux, I've included some of these below as a series of ten small, separate, simple test cases, structured in the format you've indicated you prefer. Then below that I've included another ten cases for Windows 2000 systems, in the same format: ====================================================== <?php putenv("TZ=Europe/Andorra"); $tStamp = mktime (17, 17, 17, 1, 24764, 1970); print "tStamp=". date("l Y-m-d H:i:s T", $tStamp). "\n"; $strtotime_tstamp = strtotime("Monday", $tStamp); print "result=".date("l Y-m-d H:i:s T", $strtotime_tstamp)."\n"; print "wanted=Monday 00:00:00\n\n"; putenv("TZ=Asia/Dubai"); $tStamp = mktime (17, 17, 17, 1, 1, 1970); print "tStamp=". date("l Y-m-d H:i:s T", $tStamp). "\n"; $strtotime_tstamp = strtotime("Monday", $tStamp); print "result=".date("l Y-m-d H:i:s T", $strtotime_tstamp)."\n"; print "wanted=Monday 00:00:00\n\n"; putenv("TZ=Asia/Kabul"); $tStamp = mktime (17, 17, 17, 1, 1, 1970); print "tStamp=". date("l Y-m-d H:i:s T", $tStamp). "\n"; $strtotime_tstamp = strtotime("Monday", $tStamp); print "result=".date("l Y-m-d H:i:s T", $strtotime_tstamp)."\n"; print "wanted=Monday 00:00:00\n\n"; putenv("TZ=America/Antigua"); $tStamp = mktime (17, 17, 17, 1, 1, 1970); print "tStamp=". date("l Y-m-d H:i:s T", $tStamp). "\n"; $strtotime_tstamp = strtotime("Monday", $tStamp); print "result=".date("l Y-m-d H:i:s T", $strtotime_tstamp)."\n"; print "wanted=Monday 00:00:00\n\n"; putenv("TZ=America/Anguilla"); $tStamp = mktime (17, 17, 17, 1, 1, 1970); print "tStamp=". date("l Y-m-d H:i:s T", $tStamp). "\n"; $strtotime_tstamp = strtotime("Monday", $tStamp); print "result=".date("l Y-m-d H:i:s T", $strtotime_tstamp)."\n"; print "wanted=Monday 00:00:00\n\n"; putenv("TZ=Europe/Tirane"); $tStamp = mktime (17, 17, 17, 1, 4849, 1970); print "tStamp=". date("l Y-m-d H:i:s T", $tStamp). "\n"; $strtotime_tstamp = strtotime("Monday", $tStamp); print "result=".date("l Y-m-d H:i:s T", $strtotime_tstamp)."\n"; print "wanted=Monday 00:00:00\n\n"; putenv("TZ=Asia/Yerevan"); $tStamp = mktime (17, 17, 17, 1, 24764, 1970); print "tStamp=". date("l Y-m-d H:i:s T", $tStamp). "\n"; $strtotime_tstamp = strtotime("Monday", $tStamp); print "result=".date("l Y-m-d H:i:s T", $strtotime_tstamp)."\n"; print "wanted=Monday 00:00:00\n\n"; putenv("TZ=America/Curacao"); $tStamp = mktime (17, 17, 17, 1, 1, 1970); print "tStamp=". date("l Y-m-d H:i:s T", $tStamp). "\n"; $strtotime_tstamp = strtotime("Monday", $tStamp); print "result=".date("l Y-m-d H:i:s T", $strtotime_tstamp)."\n"; print "wanted=Monday 00:00:00\n\n"; putenv("TZ=Africa/Luanda"); $tStamp = mktime (17, 17, 17, 1, 1, 1970); print "tStamp=". date("l Y-m-d H:i:s T", $tStamp). "\n"; $strtotime_tstamp = strtotime("Monday", $tStamp); print "result=".date("l Y-m-d H:i:s T", $strtotime_tstamp)."\n"; print "wanted=Monday 00:00:00\n\n"; putenv("TZ=Antarctica/McMurdo"); $tStamp = mktime (17, 17, 17, 1, 24743, 1970); print "tStamp=". date("l Y-m-d H:i:s T", $tStamp). "\n"; $strtotime_tstamp = strtotime("Monday", $tStamp); print "result=".date("l Y-m-d H:i:s T", $strtotime_tstamp)."\n"; print "wanted=Monday 00:00:00\n\n"; ?> ====================================================== Results (on my system, a Debian GNU/Linux Woody 3.0r6 box), are as follows: ludo:~/tmp/php-5.1-dev/php5-200506170030/sapi/cli# ./php ~/test/test-output.php tStamp=Monday 2037-10-19 17:17:17 CEST result=Monday 2037-10-26 01:00:00 CET wanted=Monday 00:00:00 tStamp=Thursday 1970-01-01 17:17:17 GST result=Monday 1970-01-05 04:00:00 GST wanted=Monday 00:00:00 tStamp=Thursday 1970-01-01 17:17:17 AFT result=Monday 1970-01-05 04:30:00 AFT wanted=Monday 00:00:00 tStamp=Thursday 1970-01-01 17:17:17 AST result=Sunday 1970-01-04 20:00:00 AST wanted=Monday 00:00:00 tStamp=Thursday 1970-01-01 17:17:17 AST result=Sunday 1970-01-04 20:00:00 AST wanted=Monday 00:00:00 tStamp=Monday 1983-04-11 17:17:17 CET result=Monday 1983-04-18 01:00:00 CEST wanted=Monday 00:00:00 tStamp=Monday 2037-10-19 17:17:17 AMST result=Monday 2037-10-26 04:00:00 AMT wanted=Monday 00:00:00 tStamp=Thursday 1970-01-01 17:17:17 AST result=Sunday 1970-01-04 20:00:00 AST wanted=Monday 00:00:00 tStamp=Thursday 1970-01-01 17:17:17 WAT result=Monday 1970-01-05 01:00:00 WAT wanted=Monday 00:00:00 tStamp=Monday 2037-09-28 17:17:17 NZST result=Monday 2037-10-05 13:00:00 NZDT wanted=Monday 00:00:00 ludo:~/tmp/php-5.1-dev/php5-200506170030/sapi/cli# ====================================================== However, on a windows 2000 system, the above tests work OK, but these tests do not: ====================================================== <?php putenv("TZ=Australia/Adelaide"); $tStamp = mktime (17, 17, 17, 1, 1, 1971); print "tStamp=". date("l Y-m-d H:i:s T", $tStamp). "\n"; $strtotime_tstamp = strtotime("Monday", $tStamp); print "result=".date("l Y-m-d H:i:s T", $strtotime_tstamp)."\n"; print "wanted=Monday 00:00:00\n\n"; putenv("TZ=Australia/Darwin"); $tStamp = mktime (17, 17, 17, 1, 88, 1971); print "tStamp=". date("l Y-m-d H:i:s T", $tStamp). "\n"; $strtotime_tstamp = strtotime("Monday", $tStamp); print "result=".date("l Y-m-d H:i:s T", $strtotime_tstamp)."\n"; print "wanted=Monday 00:00:00\n\n"; putenv("TZ=Australia/Perth"); $tStamp = mktime (17, 17, 17, 1, 1, 1971); print "tStamp=". date("l Y-m-d H:i:s T", $tStamp). "\n"; $strtotime_tstamp = strtotime("Monday", $tStamp); print "result=".date("l Y-m-d H:i:s T", $strtotime_tstamp)."\n"; print "wanted=Monday 00:00:00\n\n"; putenv("TZ=America/Aruba"); $tStamp = mktime (17, 17, 17, 1, 88, 1971); print "tStamp=". date("l Y-m-d H:i:s T", $tStamp). "\n"; $strtotime_tstamp = strtotime("Monday", $tStamp); print "result=".date("l Y-m-d H:i:s T", $strtotime_tstamp)."\n"; print "wanted=Monday 00:00:00\n\n"; putenv("TZ=Asia/Baku"); $tStamp = mktime (17, 17, 17, 1, 1, 1971); print "tStamp=". date("l Y-m-d H:i:s T", $tStamp). "\n"; $strtotime_tstamp = strtotime("Monday", $tStamp); print "result=".date("l Y-m-d H:i:s T", $strtotime_tstamp)."\n"; print "wanted=Monday 00:00:00\n\n"; putenv("TZ=Europe/Sarajevo"); $tStamp = mktime (17, 17, 17, 1, 1, 1971); print "tStamp=". date("l Y-m-d H:i:s T", $tStamp). "\n"; $strtotime_tstamp = strtotime("Monday", $tStamp); print "result=".date("l Y-m-d H:i:s T", $strtotime_tstamp)."\n"; print "wanted=Monday 00:00:00\n\n"; putenv("TZ=America/Barbados"); $tStamp = mktime (17, 17, 17, 1, 1, 1971); print "tStamp=". date("l Y-m-d H:i:s T", $tStamp). "\n"; $strtotime_tstamp = strtotime("Monday", $tStamp); print "result=".date("l Y-m-d H:i:s T", $strtotime_tstamp)."\n"; print "wanted=Monday 00:00:00\n\n"; putenv("TZ=Asia/Dacca"); $tStamp = mktime (17, 17, 17, 1, 1, 1971); print "tStamp=". date("l Y-m-d H:i:s T", $tStamp). "\n"; $strtotime_tstamp = strtotime("Monday", $tStamp); print "result=".date("l Y-m-d H:i:s T", $strtotime_tstamp)."\n"; print "wanted=Monday 00:00:00\n\n"; putenv("TZ=Europe/Brussels"); $tStamp = mktime (17, 17, 17, 1, 1, 1971); print "tStamp=". date("l Y-m-d H:i:s T", $tStamp). "\n"; $strtotime_tstamp = strtotime("Monday", $tStamp); print "result=".date("l Y-m-d H:i:s T", $strtotime_tstamp)."\n"; print "wanted=Monday 00:00:00\n\n"; putenv("TZ=Africa/Ouagadougou"); $tStamp = mktime (17, 17, 17, 1, 88, 1971); print "tStamp=". date("l Y-m-d H:i:s T", $tStamp). "\n"; $strtotime_tstamp = strtotime("Monday", $tStamp); print "result=".date("l Y-m-d H:i:s T", $strtotime_tstamp)."\n"; print "wanted=Monday 00:00:00\n\n"; ?> ====================================================== Results on a Windows 2000 SP4 box, are as follows: G:\PHP bugs\PHP bug 20382\php5.1-dev\php5-win32-200506171830>php-cgi.exe ..\..\new-test-output.php Content-type: text/html X-Powered-By: PHP/5.1.0-dev tStamp=Friday 1971-01-01 17:17:17 Aus result=Sunday 1971-01-03 14:30:00 Aus wanted=Monday 00:00:00 tStamp=Monday 1971-03-29 17:17:17 Aus result=Monday 1971-04-05 01:00:00 tra wanted=Monday 00:00:00 tStamp=Friday 1971-01-01 17:17:17 Aus result=Sunday 1971-01-03 16:00:00 Aus wanted=Monday 00:00:00 tStamp=Monday 1971-03-29 17:17:17 Ame result=Monday 1971-04-05 01:00:00 ric wanted=Monday 00:00:00 tStamp=Friday 1971-01-01 17:17:17 Asi result=Sunday 1971-01-03 20:00:00 Asi wanted=Monday 00:00:00 tStamp=Friday 1971-01-01 17:17:17 Eur result=Sunday 1971-01-03 23:00:00 Eur wanted=Monday 00:00:00 tStamp=Friday 1971-01-01 17:17:17 Ame result=Monday 1971-01-04 04:00:00 Ame wanted=Monday 00:00:00 tStamp=Friday 1971-01-01 17:17:17 Asi result=Sunday 1971-01-03 18:00:00 Asi wanted=Monday 00:00:00 tStamp=Friday 1971-01-01 17:17:17 Eur result=Sunday 1971-01-03 23:00:00 Eur wanted=Monday 00:00:00 tStamp=Monday 1971-03-29 17:17:17 Afr result=Monday 1971-04-05 01:00:00 ica wanted=Monday 00:00:00 G:\PHP bugs\PHP bug 20382\php5.1-dev\php5-win32-200506171830> ==================================================================== And running the win2000 tests on the Linux box give this: ludo:~/tmp/php-5.1-dev/php5-200506170030/sapi/cli# ./php ~/test/new-test-win2000.php tStamp=Friday 1971-01-01 17:17:17 CST result=Monday 1971-01-04 00:00:00 CST wanted=Monday 00:00:00 tStamp=Monday 1971-03-29 17:17:17 CST result=Monday 1971-04-05 09:30:00 CST wanted=Monday 00:00:00 tStamp=Friday 1971-01-01 17:17:17 WST result=Monday 1971-01-04 00:00:00 WST wanted=Monday 00:00:00 tStamp=Monday 1971-03-29 17:17:17 AST result=Sunday 1971-04-04 20:00:00 AST wanted=Monday 00:00:00 tStamp=Friday 1971-01-01 17:17:17 BAKT result=Monday 1971-01-04 00:00:00 BAKT wanted=Monday 00:00:00 tStamp=Friday 1971-01-01 17:17:17 CET result=Monday 1971-01-04 00:00:00 CET wanted=Monday 00:00:00 tStamp=Friday 1971-01-01 17:17:17 AST result=Monday 1971-01-04 00:00:00 AST wanted=Monday 00:00:00 tStamp=Friday 1971-01-01 17:17:17 DACT result=Monday 1971-01-04 00:00:00 DACT wanted=Monday 00:00:00 tStamp=Friday 1971-01-01 17:17:17 CET result=Monday 1971-01-04 00:00:00 CET wanted=Monday 00:00:00 tStamp=Monday 1971-03-29 17:17:17 GMT result=Monday 1971-04-05 00:00:00 GMT wanted=Monday 00:00:00 I.e. the 2nd and 4th results are also wrong on Linux, the remaining 8 look correct (so there is some overlap in incorrect results between operating systems, although most of the time there is not).That's a lot better, it takes much longer to find problems, but there are still some cases it doesn't seem to work on (using the same Debian GNU/Linux Woody 3.0r6 system), such as: =============================================================== <?php putenv("TZ=Europe/Tirane"); $tStamp = mktime (17, 17, 17, 1, 4849, 1970); print "tStamp=". date("l Y-m-d H:i:s T", $tStamp). "\n"; $strtotime_tstamp = strtotime("Monday", $tStamp); print "result=".date("l Y-m-d H:i:s T", $strtotime_tstamp)."\n"; print "wanted=Monday 00:00:00\n\n"; putenv("TZ=Asia/Yerevan"); $tStamp = mktime (17, 17, 17, 1, 4102, 1970); print "tStamp=". date("l Y-m-d H:i:s T", $tStamp). "\n"; $strtotime_tstamp = strtotime("Wednesday", $tStamp); print "result=".date("l Y-m-d H:i:s T", $strtotime_tstamp)."\n"; print "wanted=Wednesday 00:00:00\n\n"; putenv("TZ=Antarctica/Palmer"); $tStamp = mktime (17, 17, 17, 1, 1477, 1970); print "tStamp=". date("l Y-m-d H:i:s T", $tStamp). "\n"; $strtotime_tstamp = strtotime("Wednesday", $tStamp); print "result=".date("l Y-m-d H:i:s T", $strtotime_tstamp)."\n"; print "wanted=Wednesday 00:00:00\n\n"; putenv("TZ=America/Buenos_Aires"); $tStamp = mktime (17, 17, 17, 1, 1734, 1970); print "tStamp=". date("l Y-m-d H:i:s T", $tStamp). "\n"; $strtotime_tstamp = strtotime("Monday", $tStamp); print "result=".date("l Y-m-d H:i:s T", $strtotime_tstamp)."\n"; print "wanted=Monday 00:00:00\n\n"; putenv("TZ=America/Rosario"); $tStamp = mktime (17, 17, 17, 1, 1734, 1970); print "tStamp=". date("l Y-m-d H:i:s T", $tStamp). "\n"; $strtotime_tstamp = strtotime("Monday", $tStamp); print "result=".date("l Y-m-d H:i:s T", $strtotime_tstamp)."\n"; print "wanted=Monday 00:00:00\n\n"; putenv("TZ=America/Cordoba"); $tStamp = mktime (17, 17, 17, 1, 1734, 1970); print "tStamp=". date("l Y-m-d H:i:s T", $tStamp). "\n"; $strtotime_tstamp = strtotime("Monday", $tStamp); print "result=".date("l Y-m-d H:i:s T", $strtotime_tstamp)."\n"; print "wanted=Monday 00:00:00\n\n"; putenv("TZ=America/Jujuy"); $tStamp = mktime (17, 17, 17, 1, 1734, 1970); print "tStamp=". date("l Y-m-d H:i:s T", $tStamp). "\n"; $strtotime_tstamp = strtotime("Monday", $tStamp); print "result=".date("l Y-m-d H:i:s T", $strtotime_tstamp)."\n"; print "wanted=Monday 00:00:00\n\n"; putenv("TZ=America/Catamarca"); $tStamp = mktime (17, 17, 17, 1, 1734, 1970); print "tStamp=". date("l Y-m-d H:i:s T", $tStamp). "\n"; $strtotime_tstamp = strtotime("Monday", $tStamp); print "result=".date("l Y-m-d H:i:s T", $strtotime_tstamp)."\n"; print "wanted=Monday 00:00:00\n\n"; putenv("TZ=America/Mendoza"); $tStamp = mktime (17, 17, 17, 1, 1734, 1970); print "tStamp=". date("l Y-m-d H:i:s T", $tStamp). "\n"; $strtotime_tstamp = strtotime("Monday", $tStamp); print "result=".date("l Y-m-d H:i:s T", $strtotime_tstamp)."\n"; print "wanted=Monday 00:00:00\n\n"; putenv("TZ=Europe/Vienna"); $tStamp = mktime (17, 17, 17, 1, 3743, 1970); print "tStamp=". date("l Y-m-d H:i:s T", $tStamp). "\n"; $strtotime_tstamp = strtotime("Monday", $tStamp); print "result=".date("l Y-m-d H:i:s T", $strtotime_tstamp)."\n"; print "wanted=Monday 00:00:00\n\n"; putenv("TZ=Australia/Lord_Howe"); $tStamp = mktime (17, 17, 17, 1, 1, 1970); print "tStamp=". date("l Y-m-d H:i:s T", $tStamp). "\n"; $strtotime_tstamp = strtotime("Monday", $tStamp); print "result=".date("l Y-m-d H:i:s T", $strtotime_tstamp)."\n"; print "wanted=Monday 00:00:00\n\n"; putenv("TZ=Asia/Baku"); $tStamp = mktime (17, 17, 17, 1, 9490, 1970); print "tStamp=". date("l Y-m-d H:i:s T", $tStamp). "\n"; $strtotime_tstamp = strtotime("Monday", $tStamp); print "result=".date("l Y-m-d H:i:s T", $strtotime_tstamp)."\n"; print "wanted=Monday 00:00:00\n\n"; ?> =============================================================== Which for me gives: =============================================================== ludo:~/tmp/php-5.1-dev/php5-200506182230/sapi/cli# ./php ~/test/19-june-2005-linux-strtotime-tests.php tStamp=Monday 1983-04-11 17:17:17 CET result=Monday 1983-04-18 01:00:00 CEST wanted=Monday 00:00:00 tStamp=Wednesday 1981-03-25 17:17:17 YERT result=Wednesday 1981-04-01 01:00:00 YERST wanted=Wednesday 00:00:00 tStamp=Wednesday 1974-01-16 17:17:17 ART result=Wednesday 1974-01-23 01:00:00 ARST wanted=Wednesday 00:00:00 tStamp=Monday 1974-09-30 17:17:17 ART result=Monday 1974-10-07 01:00:00 ARST wanted=Monday 00:00:00 tStamp=Monday 1974-09-30 17:17:17 ART result=Monday 1974-10-07 01:00:00 ARST wanted=Monday 00:00:00 tStamp=Monday 1974-09-30 17:17:17 ART result=Monday 1974-10-07 01:00:00 ARST wanted=Monday 00:00:00 tStamp=Monday 1974-09-30 17:17:17 ART result=Monday 1974-10-07 01:00:00 ARST wanted=Monday 00:00:00 tStamp=Monday 1974-09-30 17:17:17 ART result=Monday 1974-10-07 01:00:00 ARST wanted=Monday 00:00:00 tStamp=Monday 1974-09-30 17:17:17 ART result=Monday 1974-10-07 01:00:00 ARST wanted=Monday 00:00:00 tStamp=Monday 1980-03-31 17:17:17 CET result=Sunday 1980-04-06 23:00:00 CET wanted=Monday 00:00:00 tStamp=Thursday 1970-01-01 17:17:17 EST result=Sunday 1970-01-04 23:00:00 EST wanted=Monday 00:00:00 tStamp=Monday 1995-12-25 17:17:17 AZT result=Monday 1996-01-01 01:00:00 AZST wanted=Monday 00:00:00 ludo:~/tmp/php-5.1-dev/php5-200506182230/sapi/cli# =============================================================== > About the Windows tests, they are not going to work yet because > on Windows the date() function doesn't understand timezone > names like "Asia/Dubai". This is going to be implement before > 5.1 is released if I have the time. No worries; If this does get added, feel free to let me know, and I can rerun some of the date-related tests on the Win32 platform.> They are correct because there is no 00:00 for those specific dates Ahhh - live and learn! I honestly never knew that there were timezones that did that. I had just assumed (incorrectly) they all jumped from 2 AM to 3 AM, I guess simply because that's what the timezone I live in ("Australia/Sydney") does. Thank you Derick, for all of your help in getting this problem resolved. Some quick notes regarding tying up loose ends: The win32 timezone format support for date() has been logged at http://bugs.php.net/33403 The time rendering bug in the date() function for the Lord Howe timezone has been logged at http://bugs.php.net/33402 The only thing I don't understand is the Vienna timezone one. I retried it with php5-200506201830, and it still happened. So I reran the tests, this time ignoring anything on the expected day at midnight, plus anything on the expected day at 1 AM. This was my most complete strtotime() test run to date, running overnight and taking around 11 hours, and performing 615 million date-related tests: // Approximate total number of tests = // 354 timezones // * 7 days // * 5 tests per day (e.g. "Monday", "next Tuesday", "last Thursday", "Friday +1 week", "Sunday -1 week") // * (2038 - 1970) years // * 365 days per year // * 2 checks for each strtotime result (one for correct day, one for checking time = midnight or 1 AM) // = 615,039,600 tests in total. So basically, if there's any lurking gremlins, this test had an fairly good chance of finding them. It found roughly 33 situations that seem to be giving the wrong day (one of which is Vienna, but the rest are not). This includes 2 situations which were off by > 24 hours (i.e. ask for "Monday", but returns a time on Saturday). This may be the same underlying problem as the Lord Howe thing, or something else, I honestly don't know. I've logged these at http://bugs.php.net/33414 It also found roughly 26 situations that were giving the right day, but a time that wasn't midnight or 1 AM. There can be valid 0.5 hour and 2 hour DST transitions (very rare, but they do happen), so there is a good chance that at least some of these are bogus. However, I thought it best to err on the side of caution, most especially because 17 of the 26 do not appear to involve a DST or timezone transition. I've logged these at http://bugs.php.net/33415