The problem as we saw it was this: there are two distinct possibilities of what
'mktime' returns (probably more, but we doubt that any of them are sensible).
Either 'mktime' returns a timestamp which represents seconds since the epoch
in the local timezone or it returns a timestamp which represents seconds since
the epoch in GMT.
If 'mktime' returns a timestamp in local time then the conversion to a timestamp
in GMT would be a simple one. Because under these assumptions 'mktime' is not
applying an offset (both the input and output are relative to the server) all we
need to do to convert the output is to apply the user's offset. If on the other
hand 'mktime' returns a timestamp which represents seconds since the epoch in
GMT then the conversion of the timestamp is not so simple. Remember that any
conversion applied by 'mktime' is always performed relative to the server's
timezone, so even though 'mktime' under these assumption would try to return a
time in GMT it would fail because it would apply the server's offset rather than
the user's offset. To solve this problem we would have to figure out the
difference between the server's offset and the user's offset, in other words,
the user's offset from the server, and then subtract that value from the
timestamp returned by 'mktime'.
Hopefully, this hasn't confused anyone to the point of madness like it did us.
If it has, hang on. The solution is quite simple. As all you true hardcore *nix
wizards out there already know, timestamps are always stored as seconds since
the epoch in GMT. In fact the epoch is defined as being in GMT. A a technicality
for sure, but an important one. If you keep in mind that all PHP functions
deal with timestamps in GMT then your timestamp problems will be greatly
reduced. Also, if it helps you can demonstrate that this is the case; just run
the following code:
It should return something other than 0 (unless you somehow live in GMT) thus
indicating that PHP is applying the servers offset to translate the time values
passed into 'mktime' to a timestamp that is relative to GMT.
What this means in terms of our previous discussion is that our second
hypothesis was the correct one. 'mktime' returns a timestamp representing seconds
since the epoch, the epoch being in GMT of course. Just in case there is any
lingering confusion, below is a description of what PHP's date functions do.