If you’re using PHP mktime() to make a timestamp for a specific moment in time that should not change, then be sure to first set the default timezone to UTC. Otherwise, the dynamic behavior of mktime() is to modify or change your time, based on the timezone settings on your server. This may be desirable behavior for when the time is used to display to the user, or for logging, but this is unwanted behavior for dealing with specific moments in time that must be precise (for example, birth times).
If you’re using a birth time to create a datetime string, mktime()
can make the wrong time. Here’s an example of the problem that I’m referring to.
As an example, take the date and time of March 27, 1921 at 02:00 (2:00 am).
Let’s say that I want to create a datetime string in this format: “YYY-mm-dd HH:mm”. I’ll do this:
$datetime = strftime("%Y-%m-%d %H:%M", mktime(2, 0, 0, 3, 27, 1921));
(See why I use strftime() instead of date().)
I expect $datetime
to look like this: 1921-03-27 02:00.
But, actually, it comes out like this: 1921-03-27 03:00.
It’s one hour off. This is because mktime() changed the Unix timestamp to account for whatever convoluted timezone changes it considered necessary, based on the server timezone setting.
This is a terrible mistake if you’re dealing with birth times. You would end up using an incorrect time.
This happens with almost all times near the transitions to Daylight Savings Time on any year. Here are a few more examples. PHP mktime() will screw up all of these date/times:
1933-04-30 02:00
1955-04-24 02:30
2017-03-12 02:30
2018-03-11 02:00
Here are the expected datetimes, and the actual time that mktime() makes (formatted with strftime()).
1933-04-30 02:00 <---- Expected 1933-04-30 03:00 <---- Actual 1955-04-24 02:30 <---- Expected 1955-04-24 03:30 <---- Actual 2017-03-12 02:30 <---- Expected 2017-03-12 03:30 <---- Actual 2018-03-11 02:00 <---- Expected 2018-03-11 03:00 <---- Actual
By the way, strftime() is unimportant to the problem here; it merely formats the Unix timestamp. It's the Unix timestamp, created by mktime(), thats incorrect.
The Solution
The solution is to tell mktime(), "Hey mktime(), don't change my time!"
If you don't want your Unix timestamp modified by mktime(), then add this line before using mktime():
date_default_timezone_set('UTC');
That will set the default timezone to UTC which sends the signal to mktime(), "don't modify my time!"
Questions and Comments are Welcome