ID: 42645 Comment by: dertonex at mail dot com Reported By: carstenklein at yahoo dot de Status: Assigned Bug Type: Date/time related Operating System: Linux Ubuntu Feisty Fawn PHP Version: 5.2.4 Assigned To: derick New Comment:
[3] => Array ( [0] => F14 [1] => èññèÿÍåâûïîëíèì [2] => http://netitem.net [3] => 2:01:53 [4] => http://tittle-tattle.net ) [4] => Array ( [0] => http://allscandals.net [1] => Bedazzled [2] => http://webrumours.com [3] => 1:31:47 [4] => 672 ) Previous Comments: ------------------------------------------------------------------------ [2007-10-17 20:12:27] carstenklein at yahoo dot de Additional information: it seems as if the timelib or some component thereof behaves like a clock that will only adjust the dst when transitioning from the day that the transition is being scheduled for depending on the current timezone setting. This is actually hard to figure out since the information required to find out whether there is a scheduled dst transition on a particular date is actually not available from within php, AFAIK. A more sophisticated application therefore must replicate the timezone database along with all the code in order to find out whether or not a dst transition should take place on a particular date. Here are a few pointers as to how this problem could actually be solved: a) make available dst transitioning dates via the date/time api in order for the user to find out whether or not on a particular date a dst transition will take place or b) leave it to the user whether or not to take care of dst transitioning by altogether removing existing behaviour the latter would actually break with existing applications, therefore, the initial proposal of reusing the obsoleted seventh parameter to mktime for indicating whether or not dst should be applied seems to be the less painful one. additionally, a) should also be taken into consideration in order for the user not having to reimplement a timezone database along with all the possible transition dates for applying or removing dst. Hope this helps with your task. Regards Carsten ------------------------------------------------------------------------ [2007-10-07 09:41:35] fkl at tfu dot jgfi http://www.meta-fx.com http://www.forex.co.ir forex ÝÇÑÓ ------------------------------------------------------------------------ [2007-09-13 08:09:47] [EMAIL PROTECTED] Assigned to the ext/date maintainer. :) ------------------------------------------------------------------------ [2007-09-12 18:04:30] carstenklein at yahoo dot de Small err on my behalf, where it reads: "result often are non reproducible and may seem quite random" it must read: "result are reproducible but may seem quite random" and "Therefore I urge you to at least provide a timezone offset less version of mktime in order to at least get some reproducible results." it should read "Therefore I urge you to at least provide a timezone offset less version of mktime and let the user do the rest." A provable solution would be to take the seventh, now deprecated parameter to mktime and make it a flag indicating wether or not offsets will be applied to the resulting date/time. ------------------------------------------------------------------------ [2007-09-12 16:06:37] carstenklein at yahoo dot de Description: ------------ getdate() a/o mktime() do not always add/subtract the currently valid dst offset. Actually, they do only add the dst offset under certain conditions, but not always and not to all possible normal time/summer time, summer time/normal time transitions. see below code for an example on how to reprocude the erroneous behaviour. the lines being marked with "good/failure" represent the lines where the dst offset has been added. As you can see, it happens not for all possible dates since 1970-1-1, at least in the local configuration being set to CET/CEST. BTW: opposed to what is expected, CEST to CET transitions do not seem to work at all, I was unable to setup a scenario where the dst offset would have been subtracted from the resulting timestamp. It seems as if the mktime() or timelib functions do not take dst into account when transitioning a date from summer time to normal time. I would therefore like mktime and the timelib to no longer try to guess the actual current time and automatically add the required dst offsets to either date and time as it is prone to error as one can clearly see in the below example outputs of below program fragment. Additionally, the results often are non reproducible and may seem quite random. If you don't believe, go and try for yourself, change the number of days to be added to the start date from 20 to for example 10 or other reasonable values. Furthermore, try to play with the starting date, make it some date in February instead of for example March, but make sure that you transition the date beyond the last Sunday in March, 1:00am. As you can see, the results will vary greatly. Of course one could always double check the results returned by mktime, however, this is a lot of special casing etc. Therefore I urge you to at least provide a timezone offset less version of mktime in order to at least get some reproducible results. And, using the seventh optional parameter to mktime() makes no difference at all, besides that, it is considered deprecated. similar bug reports, all having been closed so far: http://bugs.php.net/bug.php?id=245 http://bugs.php.net/bug.php?id=741 Reproduce code: --------------- <?php function addDuration( $date, $durationArray ) { $t = getdate( $date ); $t[ "year" ] += $durationArray[ "years" ]; $t[ "mon" ] += $durationArray[ "months" ]; $t[ "mday" ] += $durationArray[ "days" ]; $t[ "hours" ] += $durationArray[ "hours" ]; $t[ "minutes" ] += $durationArray[ "minutes" ]; $t[ "seconds" ] += $durationArray[ "seconds" ]; return mktime( $t[ "hours" ], $t[ "minutes" ], $t[ "seconds" ], $t[ "mon" ], $t[ "mday" ], $t[ "year" ] ); } function durationToString( $durationArray ) { return "P" . $durationArray[ "years" ] . "Y" . $durationArray[ "months" ] . "M" . $durationArray[ "days" ] . "D" . "T" . $durationArray[ "hours" ] . ":" . $durationArray[ "minutes" ] . ":" . $durationArray[ "seconds" ]; } echo "Testing Normal Time to DST Transition:\n"; for( $y = 1902; $y < 2038; $y++ ) { for( $x = 14; $x < 32; $x++ ) { $d = strtotime( "$y-03-$x 02:30:30" ); echo ( date( "Y-m-d H:i:s", $d ) ) . "\t"; $durationArray = array( "years" => 0, "months" => 0, "days" => 20, "hours" => 0, "minutes" => 0, "seconds" => 0 ); echo "+\t" . durationToString( $durationArray ) . "\t+\t"; $t = addDuration( $d, $durationArray ); $td = getdate( $t ); echo date( "Y-m-d H:i:s", $t ) . ( $td[ "hours" ] == 3 ? " <- FAILURE" : "" ) . "\n"; } } echo "Testing DST to Normal Time Transition:\n"; for( $y = 2037; $y > 1901; $y-- ) { for( $x = 24; $x < 32; $x++ ) { $d = strtotime( "$y-10-$x 00:00:10" ); echo ( date( "Y-m-d H:i:s", $d ) ) . "\t"; $durationArray = array( "years" => 0, "months" => 0, "days" => 1, "hours" => 0, "minutes" => 0, "seconds" => 0 ); echo "+\t" . durationToString( $durationArray ) . "\t+\t"; $t = addDuration( $d, $durationArray ); $td = getdate( $t ); echo date( "Y-m-d H:i:s", $t ) . ( $td[ "hours" ] == 23 ? " <- FAILURE" : "" ) . "\n"; } } ?> Expected result: ---------------- 1981-03-25 02:30:30 + P0Y0M20DT0:0:0 + 1981-04-14 03:30:30 1981-03-26 02:30:30 + P0Y0M20DT0:0:0 + 1981-04-15 03:30:30 1981-03-27 02:30:30 + P0Y0M20DT0:0:0 + 1981-04-16 03:30:30 1981-03-28 02:30:30 + P0Y0M20DT0:0:0 + 1981-04-17 03:30:30 1981-03-29 03:30:30 + P0Y0M20DT0:0:0 + 1981-04-18 03:30:30 <- FAILURE 1981-03-30 02:30:30 + P0Y0M20DT0:0:0 + 1981-04-19 02:30:30 1981-03-31 02:30:30 + P0Y0M20DT0:0:0 + 1981-04-20 02:30:30 1982-03-14 02:30:30 + P0Y0M20DT0:0:0 + 1982-04-03 02:30:30 1982-03-15 02:30:30 + P0Y0M20DT0:0:0 + 1982-04-04 02:30:30 1982-03-16 02:30:30 + P0Y0M20DT0:0:0 + 1982-04-05 02:30:30 1982-03-17 02:30:30 + P0Y0M20DT0:0:0 + 1982-04-06 02:30:30 * what is marked failure is actually the last sunday in march, 1981 Actual result: -------------- 1981-03-25 02:30:30 + P0Y0M20DT0:0:0 + 1981-04-14 02:30:30 1981-03-26 02:30:30 + P0Y0M20DT0:0:0 + 1981-04-15 02:30:30 1981-03-27 02:30:30 + P0Y0M20DT0:0:0 + 1981-04-16 02:30:30 1981-03-28 02:30:30 + P0Y0M20DT0:0:0 + 1981-04-17 02:30:30 1981-03-29 03:30:30 + P0Y0M20DT0:0:0 + 1981-04-18 03:30:30 <- FAILURE 1981-03-30 02:30:30 + P0Y0M20DT0:0:0 + 1981-04-19 02:30:30 1981-03-31 02:30:30 + P0Y0M20DT0:0:0 + 1981-04-20 02:30:30 1982-03-14 02:30:30 + P0Y0M20DT0:0:0 + 1982-04-03 02:30:30 1982-03-15 02:30:30 + P0Y0M20DT0:0:0 + 1982-04-04 02:30:30 1982-03-16 02:30:30 + P0Y0M20DT0:0:0 + 1982-04-05 02:30:30 1982-03-17 02:30:30 + P0Y0M20DT0:0:0 + 1982-04-06 02:30:30 *) what is marked as FAILURE is actually correct, however, all the other dates before also transition from non-dst to dst, in the local configuration, i.e. CET to CEST, so these should also have a local time reading of 03:30:30 instead of just 02:30:30. ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/?id=42645&edit=1