From:             [EMAIL PROTECTED]
Operating system: MacOS X 10.0.2 (Darwin)
PHP version:      4.0.5
PHP Bug Type:     Date/time related
Bug description:  Bug in "mktime()" on values out of bounds

see Bug id #8828, too!

On PHP documantation: 
mktime(hour,min,sec, year,0,mon) refers the last day of month 'mon-1'. On MacOS X this 
failed, there it refers the first day of month 'mon' and mktime(hour,min,sec,  
year,-1,mon) refers the last day of month 'mon-1'. 

On MacOS X 10.0.2 (Darwin 1.3): 
02.03  --> 983487600 --> 02.03 
01.03  --> 983401200 --> 01.03 
00.03  --> 983401200 --> 01.03 
-1.03  --> 983314800 --> 28.02 
-2.03  --> 983228400 --> 27.02 

i have check some UNIX-systems and i haven't found any man-page, where is describe 
what should be happend on "tm_mday" <= 0.  The problem is happend on all values out of 
bounds, when using mktime()!

IMHO this is a undocumented feature, which is used by PHP. 
 
man mktime (Linux 2.2.13) 
       tm_mday               The day of the month, in the range 1 to 31. 
Sun Release 4.1 
       int tm_mday;     /* day of month (1 - 31) */ 
SunOS 5.5 
       int  tm_mday;       /* day of the month - [1, 31] */ 
HP-UX Release 10.20 
       int tm_mday;     /* day of month - [1,31] */ 
HP-UX Release 11.00 
       int tm_mday;     /* day of month - [1,31] */ 
AIX 4.3.2 
       int tm_mday;    /* Day of month (1 - 31) */ 
Darwin 1.0.2 
       int tm_mday;     /* day of month (1 - 31) */ 
 
I think i should by much better to check mktime() on configure and set a #define for 
compilation. Only on "datetime.c" must be made a patch to support MacOS X's / Darwin's 
mktime()-systemcall, i think! 


Patch to make php_mktime() more compatible [i think it is not complete for the whole 
PHP4-project]. It includes a time correction for values less then 1 on "mday",
"hour", "min", "sec", "mon"!! 
 
 
*** ext/standard/datetime.c.orig        Fri Dec  8 12:38:02 2000 
--- ext/standard/datetime.c     Sun Apr 15 17:28:46 2001 
*************** 
*** 81,87 **** 
        struct tm *ta, tmbuf; 
        time_t t; 
        int i, gmadjust, seconds, arg_count = ZEND_NUM_ARGS(); 
!       int is_dst = -1; 
   
        if (arg_count > 7 ||  
zend_get_parameters_array_ex(arg_count,arguments) ==  
FAILURE) { 
                WRONG_PARAM_COUNT; 
--- 81,87 ---- 
        struct tm *ta, tmbuf; 
        time_t t; 
        int i, gmadjust, seconds, 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; 
*************** 
*** 148,172 **** 
                          - (((*arguments[5])->value.lval > 1000) ? 1900 : 0); 
                /* fall-through */ 
        case 5: 
!               ta->tm_mday = (*arguments[4])->value.lval; 
                /* fall-through */ 
        case 4: 
!               ta->tm_mon = (*arguments[3])->value.lval - 1; 
                /* fall-through */ 
        case 3: 
!               ta->tm_sec = (*arguments[2])->value.lval; 
                /* fall-through */ 
        case 2: 
!               ta->tm_min = (*arguments[1])->value.lval; 
                /* fall-through */ 
        case 1: 
!               ta->tm_hour = (*arguments[0])->value.lval; 
                /* fall-through */ 
        case 0: 
                break; 
        } 
   
!       seconds = mktime(ta); 
        if (is_dst == -1) 
                is_dst = ta->tm_isdst; 
   
--- 148,182 ---- 
                          - (((*arguments[5])->value.lval > 1000) ? 1900 : 0); 
                /* fall-through */ 
        case 5: 
!               val = (*arguments[4])->value.lval; 
!               if (val < 1) { chgsecs += (1-val) * 60*60*24; val = 1;  
} 
!               ta->tm_mday = val; 
                /* fall-through */ 
        case 4: 
!               val = (*arguments[3])->value.lval - 1; 
!               while (val < 0) { val += 12; ta->tm_year--; } 
!               ta->tm_mon = val; 
                /* fall-through */ 
        case 3: 
!               val = (*arguments[2])->value.lval; 
!               if (val < 1) { chgsecs += (1-val); val = 1; } 
!               ta->tm_sec = val; 
                /* fall-through */ 
        case 2: 
!               val = (*arguments[1])->value.lval; 
!               if (val < 1) { chgsecs += (1-val) * 60; val = 1; } 
!               ta->tm_min = val; 
                /* fall-through */ 
        case 1: 
!               val = (*arguments[0])->value.lval; 
!               if (val < 1) { chgsecs += (1-val) * 60*60; val = 1; } 
!               ta->tm_hour = val; 
                /* fall-through */ 
        case 0: 
                break; 
        } 
   
!       seconds = mktime(ta) - chgsecs; 
        if (is_dst == -1) 
                is_dst = ta->tm_isdst; 



-- 
Edit Bug report at: http://bugs.php.net/?id=10686&edit=1



-- 
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
To contact the list administrators, e-mail: [EMAIL PROTECTED]

Reply via email to