Re: gmmktime is broken [Bug #1529]
| From: | Rasmus Lerdorf | Date: | Thu, 01 Jan 1970 00:00:00 +0000 |
| Subject: | Re: gmmktime is broken [Bug #1529] | ||
| References: | 1 | Groups: | php.dev |
| Request: | Send a blank email to php-dev+get-6964@lists.php.net to get a copy of this message | ||
> The basic premise of the bug report is that I maintain that gmmktime is
> broken. The last response I received was:
>
> > This is a documentation bug. The argument you pass to gmmktime is
> > in local time, not GMT. The function would be useless, if you
> > pass in GMT and get GMT out (you could use mktime for that). It's
> > intended to be a conversion function from local time (in) to GMT
> > (out).
>
> Is this true? This seems to be incorrect to me. If I pass gmmktime a
> value of 0,0,0,1,1,1970 in my time zone (GMT -5), as the code stands, I
> would get back a value of 36000 which is:
Whoever wrote that in the bug database was confused. gmmktime() is indeed
intended to be used as you say. Both mktime() and gmmktime() spit out
stamdard unix timestamps. A unix timestamp is timezone neutral. There is
no timezone attached to them at all. Timezones are applied when it comes
time to convert the timestamp to something readable.
If you look at the _php3_mktime() function in functions/datetime.c in the
PHP source code, you will see the following snippet of code:
#if HAVE_TZSET
tzset();
#endif
tn = localtime(&t);
if (gm) {
#if HAVE_TM_GMTOFF
gmadjust=(tn->tm_gmtoff)/3600;
#else
gmadjust=timezone/3600;
#endif
}
The 'gm' variable is set when you call the function as gmmktime() and it
calculates a local timezone adjustment factor for your location. This
adjustment factor is applied to the hour argument in the gmmktime() call
with this line:
ta.tm_hour = arguments[0]->value.lval - gmadjust;
So, in my timezone (EDT) my gmadjust is current -4, so if I pass
gmmktime() a timestamp of noon, it adjusts it by adding 4 hours to it.
That is, it converts the arguments I feed gmmktime() from GMT to my local
timezone (would probably fail in the weird .5 timezones, but we'll fix
that some other day). But, this is also where your bug comes in. That
adjustment line should be:
ta.tm_hour = arguments[0]->value.lval + gmadjust;
Try making that change. The one slight weirdness here is that I think the
adjustment doesn't take daylight savings time into account. I don't have
time to look into that right now. Play around with it.
-Rasmus