ID: 8828
Updated by: derick
Reported By: [EMAIL PROTECTED]
Old-Status: Open
Status: Duplicate
Bug Type: Date/time related
Operating system: 
PHP Version: 4.0.4pl1
Assigned To: 
Comments:

Dup of #10686

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

[2001-04-16 03:20:21] [EMAIL PROTECTED]
Now for tm_mon < 0, too:

*** 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;
  


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

[2001-04-15 10:59:06] [EMAIL PROTECTED]
FIRST 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". NOT on "mon"!!


*** ext/standard/datetime.c.orig        Fri Dec  8 12:38:02 2000
--- ext/standard/datetime.c     Sun Apr 15 16:42:37 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,180 ----
                          - (((*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:
                ta->tm_mon = (*arguments[3])->value.lval - 1;
                /* 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;


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

[2001-03-14 15:56:42] [EMAIL PROTECTED]
I was incorrect, This is not a part of C99(ANSI/ISO/IEC9899-1999) this is just 
implemented in Solaris, Linux, Irix, and possibly a few others.

-Jason

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

[2001-03-14 13:34:47] [EMAIL PROTECTED]
This actually is part of the Ansi C standard.

Solaris 8 manpage -----------------------

The original values of the components may be either greater than or less than the 
specified range. For example, a tm_hour of -1 means 1 hour before midnight, tm_mday of 
0 means the day preceding the current month, and tm_mon of -2 means 2 months before 
January of tm_year


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

Alg from c standard
----------------------------------------

#define QUOT(a,b) ((a)>0 ? (a)/(b) : -(((b)-(a)-1)/(b)))
#define REM(a,b) ((a)-(b)*QUOT(a,b))

SS = tm_hour*3600 + tm_min*60 + tm_sec +
  (tm_leapsecs == _NO_LEAP_SECONDS ? X1 :
                 tm_leapsecs) -
  (tm_zone == _LOCALTIME ? X2 : tm_zone) * 60;

// X1 is the appropriate number of leap seconds, determined by
// the implementation, or 0 if it cannot be determined. 
// X2 is the appropriate offset from local time to UTC,
// determined by the implementation, or

// (tm_isdst >= 0 ? tm_isdst : 0)
// if the offset cannot be determined

         M = REM(tm_mon, 12);
         Y = tm_year + 1900 + QUOT(tm_mon, 12);
         Z = Y - (M < 2 ? 1 : 0);
         D = Y*365 + (Z/400)*97 + (Z%400)/4 +
         M[(int []){0,31,59,90,120,151,181,212,243,273,
                               304,335}] +
        tm_mday + QUOT(SS, 86400);
               S = REM(SS, 86400);
------------------------------------------------------
Mac OS X is not following this standard

-Jason


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

[2001-01-27 07:26:19] [EMAIL PROTECTED]
I have send a bug report to darwin-developers and 
apple, too, but

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.
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!


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

The remainder of the comments for this report are too long.  To view the rest of the 
comments, please view the bug report online.


ATTENTION! Do NOT reply to this email!
To reply, use the web interface found at http://bugs.php.net/?id=8828&edit=2


-- 
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