Signature
mktime(
int $hour,
?int $minute = null,
?int $second = null,
?int $month = null,
?int $day = null,
?int $year = null
): int|falsePurpose
mktime() builds a Unix timestamp from separate date and time parts. The timestamp counts seconds since the Unix Epoch, 1970-01-01 00:00:00 GMT. The parts are interpreted in the current default timezone, so the same arguments can give different timestamps under different timezone settings. Use gmmktime() when the parts are meant as GMT.
The function is handy when you have numbers such as an hour, a month and a day, for example from a form or a calendar grid, and need a single integer that date() can format.
Signature
Parameters and defaults
houris required. Since PHP 8.0, callingmktime()with no arguments throwsArgumentCountError. Usetime()when you want the current timestamp.minuteandsecondare the minute and second within the hour and minute.month,dayandyearcome last, in that unusual order: month, day, year.- Every optional argument that is omitted or
nulltakes the current local value. A call such asmktime(0)therefore depends on the clock and is not repeatable. Pass every part when you need a deterministic result. - A
yearfrom 0 to 69 maps to 2000–2069, and 70 to 100 maps to 1970–2000. Prefer four-digit years.
Return value and failure
The function returns an integer timestamp. It returns false if the result does not fit in a PHP integer. In practice that is rare on 64-bit builds, but code that accepts arbitrary user input should still check for false before formatting the value.
Example 1: a basic timestamp
The timezone is set to UTC so the numbers are predictable.
date_default_timezone_set('UTC');
$ts = mktime(14, 30, 15, 7, 4, 2024);
echo $ts, "\n";
echo date('Y-m-d H:i:s', $ts), "\n";
echo date('l', $ts), "\n";1720103415 2024-07-04 14:30:15 Thursday
The integer can be stored, compared or passed to date() for any display format.
Example 2: out-of-range values are normalized
Values outside the normal range roll over into the next or previous unit. Month 13 is January of the next year, and day 0 is the last day of the previous month. Large hour, minute and second values carry upward.
date_default_timezone_set('UTC');
echo date('Y-m-d', mktime(0, 0, 0, 13, 1, 2024)), "\n";
echo date('Y-m-d', mktime(0, 0, 0, 12, 32, 2024)), "\n";
echo date('Y-m-d', mktime(0, 0, 0, 3, 0, 2024)), "\n";
echo date('Y-m-d H:i:s', mktime(25, 61, 61, 1, 1, 2024)), "\n";2025-01-01 2025-01-01 2024-02-29 2024-01-02 02:02:01
This behavior makes date arithmetic short, but it also means mktime() will never tell you that an input such as February 31 is invalid. It quietly converts it to a different date.
Example 3: date arithmetic and two-digit years
date_default_timezone_set('UTC');
function addDays(int $month, int $day, int $year, int $days): string
{
return date('Y-m-d', mktime(0, 0, 0, $month, $day + $days, $year));
}
$result = [
'next' => addDays(2, 20, 2024, 15),
'feb2023Days' => (int) date('t', mktime(0, 0, 0, 3, 0, 2023)),
'year69' => date('Y', mktime(0, 0, 0, 1, 1, 69)),
'year70' => date('Y', mktime(0, 0, 0, 1, 1, 70)),
];
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";{"next":"2024-03-06","feb2023Days":28,"year69":"2069","year70":"1970"}
Adding days to the day argument lets PHP handle month lengths and leap years. Asking for day 0 of March gives the final day of February, which is a common way to find a month's length.
Edge cases
- Daylight saving time: Building a date with
mktime()is usually safer than adding a fixed number of seconds per day, because a local day is not always 86,400 seconds long. Times that are skipped or repeated at a clock change still need care. - Midnight:
mktime(0, 0, 0, ...)gives local midnight at the start of that day, not a UTC timestamp, unless the default timezone is UTC. - Negative values: Negative hours, minutes, seconds, months and days count backward from the start of the relevant unit.
- Range on 32-bit systems: Where
time_tis a 32-bit signed integer, the usable years are roughly 1901 to 2038.
Common mistakes
- Writing the arguments in year, month, day order. The correct order is month, day, year.
- Leaving out trailing arguments and expecting zero. Omitted values mean the current local value.
- Treating
mktime()as a validator. Usecheckdate()first when an impossible date must be rejected. - Forgetting the timezone. Set it explicitly, or use
gmmktime()orDateTimeImmutablewith a named zone. - Using two-digit years and expecting the current century.
- Calling
mktime()with no arguments. Usetime()instead.
Related functions
gmmktime()builds a timestamp from GMT parts.checkdate()validates a Gregorian date.date()formats a timestamp.time()returns the current timestamp.DateTimeImmutableoffers an object-based API with explicit timezones.
Recap
mktime() converts hour, minute, second, month, day and year into an integer timestamp in the default timezone. Remember the month-day-year order, pass every part when you need a repeatable result, and rely on its normalization for arithmetic. It does not validate dates, and it returns false only when the result cannot fit in an integer.
Tested examples
date_default_timezone_set('UTC');
$ts = mktime(14, 30, 15, 7, 4, 2024);
echo $ts, "\n";
echo date('Y-m-d H:i:s', $ts), "\n";
echo date('l', $ts), "\n";1720103415 2024-07-04 14:30:15 Thursday
date_default_timezone_set('UTC');
echo date('Y-m-d', mktime(0, 0, 0, 13, 1, 2024)), "\n";
echo date('Y-m-d', mktime(0, 0, 0, 12, 32, 2024)), "\n";
echo date('Y-m-d', mktime(0, 0, 0, 3, 0, 2024)), "\n";
echo date('Y-m-d H:i:s', mktime(25, 61, 61, 1, 1, 2024)), "\n";2025-01-01 2025-01-01 2024-02-29 2024-01-02 02:02:01
date_default_timezone_set('UTC');
function addDays(int $month, int $day, int $year, int $days): string
{
return date('Y-m-d', mktime(0, 0, 0, $month, $day + $days, $year));
}
$result = [
'next' => addDays(2, 20, 2024, 15),
'feb2023Days' => (int) date('t', mktime(0, 0, 0, 3, 0, 2023)),
'year69' => date('Y', mktime(0, 0, 0, 1, 1, 69)),
'year70' => date('Y', mktime(0, 0, 0, 1, 1, 70)),
];
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";{"next":"2024-03-06","feb2023Days":28,"year69":"2069","year70":"1970"}