MFB test case for bug #27719 and improve comments in this tricky DST code

This commit is contained in:
Rasmus Lerdorf 2004-03-28 15:03:56 +00:00
parent 9be3c9388b
commit 1ece5eb5ad
3 changed files with 81 additions and 5 deletions

1
NEWS
View File

@ -1,6 +1,7 @@
PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ????? 2004, PHP 5 Release Candidate 2
- Fixed bug #27719 (mktime issues on and around DST changeover). (Rasmus)
- Changed sqlite to use studlyCaps convention for its OO API. (Marcus)
- Force destructors to have empty signatures. (Marcus)
- Stopped file uploads from throwing E_WARNINGs and E_NOTICEs which can not be

View File

@ -158,7 +158,7 @@ void php_mktime(INTERNAL_FUNCTION_PARAMETERS, int gm)
ta->tm_year = Z_LVAL_PP(arguments[5])
- ((Z_LVAL_PP(arguments[5]) > 1000) ? 1900 : 0);
/* fall-through */
case 5: /* day in month (1-baesd) */
case 5: /* day in month (1-based) */
val = (*arguments[4])->value.lval;
if (val < 1) {
chgsecs += (1-val) * 60*60*24;
@ -190,10 +190,10 @@ void php_mktime(INTERNAL_FUNCTION_PARAMETERS, int gm)
case 1: /* hour */
val = (*arguments[0])->value.lval;
/*
We don't use 1 here to work around problems in some mktime implementations
when it comes to daylight savings time. Setting it to 4 and working back from
there with the chgsecs offset makes us immune to these problems.
See http://bugs.php.net/27533 for more info.
We avoid midnight and a couple of hours after midnight here to work around
various OS-level bugs in mktime and specifically daylight savings time issues
in many mktime implementation.
See bugs #27533 and #27719 for more info.
*/
if (val < 4) {
chgsecs += (4-val) * 60*60; val = 4;
@ -215,6 +215,11 @@ void php_mktime(INTERNAL_FUNCTION_PARAMETERS, int gm)
seconds = t - chgsecs;
/*
Here we check to see if the chgsecs fuzz factor we applied caused us to
move from dst to non-dst or vice-versa. If so we adjust accordingly to
avoid being off by an hour on the dst changeover date.
*/
if (is_dst == -1) {
struct tm t1, t2;
t1 = *localtime(&t);
@ -225,6 +230,11 @@ void php_mktime(INTERNAL_FUNCTION_PARAMETERS, int gm)
ta = localtime(&seconds);
}
/*
If the user didn't specify whether the timestamp passed in was dst or not
then we fill it in based on the dst setting at the evaluated timestamp
at the current TZ
*/
is_dst = ta->tm_isdst;
}

View File

@ -0,0 +1,65 @@
--TEST--
Bug #27719: mktime returns incorrect timestamp for dst days
--FILE--
<?php
putenv("TZ=EST"); // No DST
$a = mktime(0, 0, 0, 4, 4, 2004, 0);
$b = mktime(0, 0, 0, 4, 4, 2004, 1);
$c = mktime(0, 0, 0, 4, 4, 2004, -1);
echo "$a ".date("m/d/y h:i:s\n",$a);
echo "$b ".date("m/d/y h:i:s\n",$b);
echo "$c ".date("m/d/y h:i:s\n",$c);
echo "\n";
putenv("TZ=EST5DST"); // DST not in effect
$a = mktime(0, 0, 0, 2, 4, 2004, 0);
$b = mktime(0, 0, 0, 2, 4, 2004, 1);
$c = mktime(0, 0, 0, 2, 4, 2004, -1);
echo "$a ".date("m/d/y h:i:s\n",$a);
echo "$b ".date("m/d/y h:i:s\n",$b);
echo "$c ".date("m/d/y h:i:s\n",$c);
echo "\n";
putenv("TZ=EST5DST"); // Just before DST changeover
$a = mktime(0, 0, 0, 4, 4, 2004, 0);
$b = mktime(0, 0, 0, 4, 4, 2004, 1);
$c = mktime(0, 0, 0, 4, 4, 2004, -1);
echo "$a ".date("m/d/y h:i:s\n",$a);
echo "$b ".date("m/d/y h:i:s\n",$b);
echo "$c ".date("m/d/y h:i:s\n",$c);
echo "\n";
putenv("TZ=EST5DST"); // Just after DST changeover
$a = mktime(3, 0, 0, 4, 4, 2004, 0);
$b = mktime(3, 0, 0, 4, 4, 2004, 1);
$c = mktime(3, 0, 0, 4, 4, 2004, -1);
echo "$a ".date("m/d/y h:i:s\n",$a);
echo "$b ".date("m/d/y h:i:s\n",$b);
echo "$c ".date("m/d/y h:i:s\n",$c);
echo "\n";
putenv("TZ=EST5DST"); // DST in effect
$a = mktime(0, 0, 0, 6, 4, 2004, 0);
$b = mktime(0, 0, 0, 6, 4, 2004, 1);
$c = mktime(0, 0, 0, 6, 4, 2004, -1);
echo "$a ".date("m/d/y h:i:s\n",$a);
echo "$b ".date("m/d/y h:i:s\n",$b);
echo "$c ".date("m/d/y h:i:s\n",$c);
echo "\n";
?>
--EXPECT--
1081054800 04/04/04 12:00:00
1081054800 04/04/04 12:00:00
1081054800 04/04/04 12:00:00
1075870800 02/04/04 12:00:00
1075867200 02/03/04 11:00:00
1075870800 02/04/04 12:00:00
1081054800 04/04/04 12:00:00
1081051200 04/03/04 11:00:00
1081054800 04/04/04 12:00:00
1081065600 04/04/04 04:00:00
1081062000 04/04/04 03:00:00
1081062000 04/04/04 03:00:00
1086325200 06/04/04 01:00:00
1086321600 06/04/04 12:00:00
1086321600 06/04/04 12:00:00