Professional Web Applications Themes

#20382 [Com]: strtotime ("Monday", $date) can produce incorrect output - PHP Development

ID: 20382 Comment by: pierre dot baudracco at aliacom dot fr Reported By: nickj-phpbugs at nickj dot org Status: Verified Bug Type: Date/time related Operating System: All PHP Version: 4.3.0-dev New Comment: This bug is reappearing this week from monday 2003-10-20. Which is a week having a daylight saving transition (this week-end). Previous Comments: ------------------------------------------------------------------------ [2003-04-06 18:47:03] scottmacvicar at ntlworld dot com This is a DST problem by the looks of it. The specific dates mentioned are when DST takes effect which is the last sunday in March. ------------------------------------------------------------------------ [2002-11-12 19:46:28] nickj-phpbugs at nickj dot org OK, I decided that ...

  1. #1

    Default #20382 [Com]: strtotime ("Monday", $date) can produce incorrect output

    ID: 20382
    Comment by: pierre dot baudracco at aliacom dot fr
    Reported By: nickj-phpbugs at nickj dot org
    Status: Verified
    Bug Type: Date/time related
    Operating System: All
    PHP Version: 4.3.0-dev
    New Comment:

    This bug is reappearing this week from monday 2003-10-20.
    Which is a week having a daylight saving transition (this week-end).


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

    [2003-04-06 18:47:03] scottmacvicar at ntlworld dot com

    This is a DST problem by the looks of it. The specific dates mentioned
    are when DST takes effect which is the last sunday in March.

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

    [2002-11-12 19:46:28] nickj-phpbugs at nickj dot org

    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:
    ============================================
    [rootwww 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>
    [rootwww 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 18:10:27] nickj-phpbugs at nickj dot org

    Happy to comply. I tried it with the CVS snapshot (php4-200211122230),
    output was:
    ================================================== ===========
    [rootwww 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>
    [rootwww 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:
    [url]http://www.dstc.qut.edu.au/DST/marg/daylight.html[/url] - "[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);

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

    [2002-11-12 06:17:41] [email]sniperphp.net[/email]

    Please try using this CVS snapshot:

    [url]http://snaps.php.net/php4-latest.tar.gz[/url]

    For Windows:

    [url]http://snaps.php.net/win32/php4-win32-latest.zip[/url]


    Your script produces the expected dates for me with latest CVS
    snapshot. Please give try it out.


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

    [2002-11-12 02:11:16] nickj-phpbugs at nickj dot org

    Strtotime() appears to produce incorrect output under some
    cirstances - 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:
    ================================================== =====
    [rootwww 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>
    [rootwww 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


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


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

    pierre dot baudracco at aliacom dot fr Guest

  2. #2

    Default #20382 [Com]: strtotime ("Monday", $date) can produce incorrect output

    ID: 20382
    Comment by: Robert at steelrat dot homeip dot net
    Reported By: nickj-phpbugs at nickj dot org
    Status: Verified
    Bug Type: Date/time related
    Operating System: All
    PHP Version: 4.3.0-dev
    New Comment:

    I can confirm that the above problem has re-occured for me! I'm using
    Windows Server 2003 and latest rc of PHP. My code is simple:

    $today = strtotime("today GMT");
    echo "Next Friday is ".date( "l, j F, Y", strtotime("first Friday",
    $today))."!<p>\n";
    print "PHP version: " . phpversion(). "<br>\n";

    and the result:

    Next Friday is Thursday, 30 October, 2003!

    PHP version: 4.3.4RC2

    I use this function on one of my pages and I've only just seen this
    appear. Worked perfectly until today!


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

    [2003-10-21 06:37:52] pierre dot baudracco at aliacom dot fr

    This bug is reappearing this week from monday 2003-10-20.
    Which is a week having a daylight saving transition (this week-end).

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

    [2003-04-06 18:47:03] scottmacvicar at ntlworld dot com

    This is a DST problem by the looks of it. The specific dates mentioned
    are when DST takes effect which is the last sunday in March.

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

    [2002-11-12 19:46:28] nickj-phpbugs at nickj dot org

    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:
    ============================================
    [rootwww 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>
    [rootwww 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 02:11:16] nickj-phpbugs at nickj dot org

    Strtotime() appears to produce incorrect output under some
    cirstances - 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:
    ================================================== =====
    [rootwww 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>
    [rootwww 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


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


    --
    Edit this bug report at [url]http://bugs.php.net/?id=20382&edit=1[/url]
    Robert at steelrat dot homeip dot net Guest

  3. #3

    Default #20382 [Com]: strtotime ("Monday", $date) can produce incorrect output

    ID: 20382
    Comment by: bostjan dot skufca at domenca dot com
    Reported By: nickj-phpbugs at nickj dot org
    Status: Verified
    Bug Type: Date/time related
    Operating System: *
    PHP Version: 4CVS, 5CVS
    Assigned To: hholzgra
    New Comment:

    mktime() constantly returns timestamp that which is exactly one year
    behind real (or better - correct) even if I leave year parameter out
    completely or specify correct year manually - so I use 2004 to get
    timestamps for 2003.


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

    [2003-04-06 18:47:03] scottmacvicar at ntlworld dot com

    This is a DST problem by the looks of it. The specific dates mentioned
    are when DST takes effect which is the last sunday in March.

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

    [2002-11-12 19:46:28] nickj-phpbugs at nickj dot org

    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:
    ============================================
    [rootwww 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>
    [rootwww 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 02:11:16] nickj-phpbugs at nickj dot org

    Strtotime() appears to produce incorrect output under some
    cirstances - 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:
    ================================================== =====
    [rootwww 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>
    [rootwww 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


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


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

  4. #4

    Default #20382 [Com]: strtotime ("Monday", $date) can produce incorrect output

    ID: 20382
    Comment by: bostjan dot skufca at domenca dot com
    Reported By: nickj-phpbugs at nickj dot org
    Status: Verified
    Bug Type: Date/time related
    Operating System: *
    PHP Version: 4CVS, 5CVS
    Assigned To: hholzgra
    New Comment:

    Disregard my previous post please!


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

    [2003-12-15 12:22:53] bostjan dot skufca at domenca dot com

    mktime() constantly returns timestamp that which is exactly one year
    behind real (or better - correct) even if I leave year parameter out
    completely or specify correct year manually - so I use 2004 to get
    timestamps for 2003.

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

    [2003-04-06 18:47:03] scottmacvicar at ntlworld dot com

    This is a DST problem by the looks of it. The specific dates mentioned
    are when DST takes effect which is the last sunday in March.

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

    [2002-11-12 19:46:28] nickj-phpbugs at nickj dot org

    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:
    ============================================
    [rootwww 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>
    [rootwww 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 02:11:16] nickj-phpbugs at nickj dot org

    Strtotime() appears to produce incorrect output under some
    cirstances - 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:
    ================================================== =====
    [rootwww 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>
    [rootwww 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


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


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

Similar Threads

  1. #39959 [NEW]: date "w" returns incorrect data
    By testingthis222 at hotmail dot com in forum PHP Bugs
    Replies: 3
    Last Post: December 27th, 03:00 PM
  2. Replies: 4
    Last Post: October 5th, 04:48 PM
  3. Replies: 0
    Last Post: August 5th, 01:25 AM
  4. Replies: 0
    Last Post: August 5th, 12:30 AM
  5. Replies: 0
    Last Post: August 4th, 10:29 PM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139