mktime
Builds a Unix timestamp from individual hour, minute, second, month, day and year values.
mktime(int $hour, ?int $minute = null, ?int $second = null, ?int $month = null, ?int $day = null, ?int $year = null): int|false- Added in PHP 4.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$hour | int | The hour, 0-23. Required since PHP 8.0. |
$minuteoptional | ?int= null | The minute. Defaults to the current local minute when omitted or null. |
$secondoptional | ?int= null | The second. Defaults to the current local second when omitted or null. |
$monthoptional | ?int= null | The month number, 1-12. Defaults to the current local month when omitted or null. |
$dayoptional | ?int= null | The day of the month. Defaults to the current local day when omitted or null. |
$yearoptional | ?int= null | The four-digit year. Defaults to the current local year when omitted or null. |
Return value
int|falseThe Unix timestamp for the given local date and time, or false on failure.
Errors
Emits E_WARNING if the default time zone is not valid. Calling mktime() with no arguments is a fatal ArgumentCountError as of PHP 8.0.
Changelog
- PHP 8.0.0hour is no longer optional. Use time() if you just need the current timestamp.
- PHP 8.0.0minute, second, month, day and year are nullable now.
mktime() turns loose numbers into a timestamp, interpreting them in the script's default time zone. Its counterpart gmmktime() does the same in UTC.
When to reach for it
Use it when the date parts already exist as separate integers — three <select> fields from a form, columns from a legacy table, or values you computed. It is also the shortest way to express date arithmetic that must respect calendar length: the last day of any month is mktime(0, 0, 0, $month + 1, 0, $year), because day 0 means "the day before the first".
What trips people up
The argument order is genuinely strange: time parts come first, and within the date the month precedes the day. Swapping those two silently produces a real but wrong date whenever both values are 12 or less.
Out-of-range values do not fail — they roll over. Month 13 becomes January of the next year, day 32 of January becomes 1 February, hour 25 becomes 01:00 tomorrow. That is useful for arithmetic but useless for validation: run user input through checkdate() first if you need to reject 31 February.
Since PHP 8.0 the hour is mandatory. Old code calling mktime() bare to mean "now" throws an ArgumentCountError; replace it with time().
Example
When to use it
- Turn separate year, month and day form fields into one storable timestamp
- Find the last day of a month with mktime(0, 0, 0, $month + 1, 0, $year)
- Compute a date N months ahead while letting the calendar handle the roll-over
Frequently asked questions
Why does mktime take month before day?
It is a historical argument order inherited from early PHP and never changed for backward compatibility. If the order bothers you, use strtotime('2025-06-15') or DateTimeImmutable instead.
Why does mktime with no arguments fail in PHP 8?
The hour parameter became required in PHP 8.0. Use time() to get the current timestamp.
What is the difference between mktime and gmmktime?
mktime interprets the values in the script's default time zone; gmmktime interprets them as UTC. The same arguments produce different timestamps unless your default zone is UTC.
More examples
Last day of every quarter
Passing day 0 of the following month lands on the final day of the month you care about, so the loop prints 31 March, 30 June, 30 September and 31 December without any leap-year or 30/31 logic.
<?php
date_default_timezone_set('UTC');
$year = 2025;
foreach ([3, 6, 9, 12] as $month) {
$end = mktime(23, 59, 59, $month + 1, 0, $year);
echo date('Y-m-d H:i:s', $end), "\n";
}Validate before you build
30 February is rejected by checkdate but silently converted to 2 March by mktime. The last line shows exactly what would have been stored had the guard been missing.
<?php
date_default_timezone_set('UTC');
$input = ['y' => 2025, 'm' => 2, 'd' => 30];
if (!checkdate($input['m'], $input['d'], $input['y'])) {
echo "rejected: that date does not exist\n";
} else {
echo date('Y-m-d', mktime(0, 0, 0, $input['m'], $input['d'], $input['y'])), "\n";
}
// without the guard, mktime would have accepted it:
echo 'mktime would give: ', date('Y-m-d', mktime(0, 0, 0, 2, 30, 2025)), "\n";
Discussion