Browse Source

fix for bug #10616 -> mktime() with negative date offsets not working on MacOSX

experimental/new_apache_hooks
Hartmut Holzgraefe 24 years ago
parent
commit
808dd7dd5f
  1. 89
      ext/standard/datetime.c
  2. 44
      ext/standard/tests/time/003.phpt

89
ext/standard/datetime.c

@ -80,10 +80,10 @@ PHP_FUNCTION(time)
void php_mktime(INTERNAL_FUNCTION_PARAMETERS, int gm)
{
pval **arguments[7];
struct tm *ta, tmbuf;
time_t t;
int i, gmadjust, seconds, arg_count = ZEND_NUM_ARGS();
int is_dst = -1;
struct tm *ta, tmbuf, *t1, *t2;
time_t t, seconds;
int i, gmadjust, arg_count = ZEND_NUM_ARGS();
int is_dst = -1, val, chgsecs = 0;
if (arg_count > 7 || zend_get_parameters_array_ex(arg_count, arguments) == FAILURE) {
WRONG_PARAM_COUNT;
@ -118,10 +118,10 @@ void php_mktime(INTERNAL_FUNCTION_PARAMETERS, int gm)
** Now change date values with supplied parameters.
*/
switch(arg_count) {
case 7:
case 7: /* daylight saving time flag */
ta->tm_isdst = is_dst = Z_LVAL_PP(arguments[6]);
/* fall-through */
case 6:
case 6: /* year */
/* special case:
a zero in year, month and day is considered illegal
as it would be interpreted as 30.11.1999 otherwise
@ -149,29 +149,64 @@ 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:
ta->tm_mday = Z_LVAL_PP(arguments[4]);
/* fall-through */
case 4:
ta->tm_mon = Z_LVAL_PP(arguments[3]) - 1;
/* fall-through */
case 3:
ta->tm_sec = Z_LVAL_PP(arguments[2]);
/* fall-through */
case 2:
ta->tm_min = Z_LVAL_PP(arguments[1]);
/* fall-through */
case 1:
ta->tm_hour = Z_LVAL_PP(arguments[0]);
/* fall-through */
case 0:
break;
}
case 5: /* day in month (1-baesd) */
val = (*arguments[4])->value.lval;
if (val < 1) {
chgsecs += (1-val) * 60*60*24;
val = 1;
}
ta->tm_mday = val;
/* fall-through */
case 4: /* month (zero-based) */
val = (*arguments[3])->value.lval - 1;
while (val < 0) {
val += 12; ta->tm_year--;
}
ta->tm_mon = val;
/* fall-through */
case 3: /* second */
val = (*arguments[2])->value.lval;
if (val < 1) {
chgsecs += (1-val); val = 1;
}
ta->tm_sec = val;
/* fall-through */
case 2: /* minute */
val = (*arguments[1])->value.lval;
if (val < 1) {
chgsecs += (1-val) * 60; val = 1;
}
ta->tm_min = val;
/* fall-through */
case 1: /* hour */
val = (*arguments[0])->value.lval;
if (val < 1) {
chgsecs += (1-val) * 60*60; val = 1;
}
ta->tm_hour = val;
/* fall-through */
case 0:
break;
}
t = mktime(ta);
seconds = t - chgsecs;
seconds = mktime(ta);
if (is_dst == -1)
is_dst = ta->tm_isdst;
if (is_dst == -1) {
struct tm t1, t2;
t1 = *localtime(&t);
t2 = *localtime(&seconds);
if(t1.tm_isdst != t2.tm_isdst) {
seconds += (t1.tm_isdst == 1) ? 3600 : -3600;
ta = localtime(&seconds);
}
is_dst = ta->tm_isdst;
}
if (gm) {
#if HAVE_TM_GMTOFF
/*

44
ext/standard/tests/time/003.phpt

@ -0,0 +1,44 @@
--TEST--
Check for mktime with out-of-range parameters
--SKIPIF--
--POST--
--GET--
--FILE--
<?php
# MacOS/X libc implementation doesn't treat out-of-range values
# the same way other unices do (Bug# 10686) so some extra code
# was added to datetime.c to take care of this
echo date("Y-m-d", mktime( 12, 0, 0, 3, 0, 2000)) ."\n";
echo date("Y-m-d", mktime( 12, 0, 0, 3, -1, 2000)) ."\n";
echo date("Y-m-d", mktime( 12, 0, 0, 2, 29, 2000)) ."\n";
echo date("Y-m-d", mktime( 12, 0, 0, 3, 0, 2001)) ."\n";
echo date("Y-m-d", mktime( 12, 0, 0, 2, 29, 2001)) ."\n";
echo date("Y-m-d", mktime( 12, 0, 0, 0, 0, 2000)) ."\n";
putenv("TZ=CET");
echo date("Y-m-d H:i:s", mktime(12,0,0,3,+90,2000,-1))."\n";
echo date("Y-m-d H:i:s", mktime(12,0,0,3,+90,2000,0))."\n";
echo date("Y-m-d H:i:s", mktime(12,0,0,3,+90,2000,1))."\n";
echo date("Y-m-d H:i:s", mktime(12,0,0,5,-90,2000,-1))."\n";
echo date("Y-m-d H:i:s", mktime(12,0,0,5,-90,2000,0))."\n";
echo date("Y-m-d H:i:s", mktime(12,0,0,5,-90,2000,1))."\n";
echo date("Y-m-d H:i:s", mktime(12,0,0,5,-1,2000,-1))."\n";
echo date("Y-m-d H:i:s", mktime(12,0,0,5,-1,2000,0))."\n";
echo date("Y-m-d H:i:s", mktime(12,0,0,5,-1,2000,1))."\n";
?>
--EXPECT--
2000-02-29
2000-02-28
2000-02-29
2001-02-28
2001-03-01
1999-11-30
2000-05-29 12:00:00
2000-05-29 13:00:00
2000-05-29 12:00:00
2000-01-31 12:00:00
2000-01-31 12:00:00
2000-01-31 11:00:00
2000-04-29 12:00:00
2000-04-29 13:00:00
2000-04-29 12:00:00
Loading…
Cancel
Save