Web & Software Developer

PHP mktime() Changes Your Time, Here’s the Fix

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():


That will set the default timezone to UTC which sends the signal to mktime(), "don't modify my time!"


Questions and Comments are Welcome

Your email address will not be published. All comments will be moderated.

Please wrap code in "code" bracket tags like this: