strftime
Formats a timestamp using locale-aware C-style format codes; deprecated since PHP 8.1.
strftime(string $format, ?int $timestamp = null): string|false- Added in PHP 4.0
- Deprecated since PHP 8.1.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$format | string | A format string of C-style conversion specifiers such as %Y, %m, %d, %H, %A and %B. |
$timestampoptional | ?int= null | The Unix timestamp to format. Defaults to the current local time when omitted or null. |
Return value
string|falseThe formatted string according to the given format, or false on failure.
Errors
Emits E_DEPRECATED on every call as of PHP 8.1.0, and E_WARNING if the default time zone is not valid.
Changelog
- PHP 8.1.0The function is deprecated. Use date() or IntlDateFormatter::format() instead.
- PHP 8.0.0timestamp is nullable now.
strftime() formats a timestamp with C-style % specifiers and, unlike date(), produces month and weekday names in the locale set by setlocale(LC_TIME, ...). That localisation was its only real advantage, and it is also why it is now deprecated.
Why it is going away
PHP 8.1 deprecated it because the behaviour was never PHP's own: it delegated to the platform C library, so the available specifiers, the output and even whether a call worked at all varied between Linux, macOS and Windows. %e and %T are missing on Windows; locale names differ everywhere. It still exists in PHP 8.5, but every call emits an E_DEPRECATED notice.
What to use instead
For English or fixed formats, date() is a direct replacement: %Y-%m-%d becomes Y-m-d, %H:%M:%S becomes H:i:s, %A becomes l, %B becomes F. For genuinely localised output, use IntlDateFormatter from the intl extension, which uses ICU data rather than the host's locale files and gives correct results for languages with declined month names.
Note that setlocale() is process-wide and not thread-safe, so on some SAPIs one request could change the locale another request sees.
Example
When to use it
- Read and understand a legacy codebase that still formats dates with % specifiers
- Migrate old strftime format strings to their date() equivalents
- Produce locale-specific month names in code that predates the intl extension
Frequently asked questions
Is strftime removed in PHP 8.5?
No, it still exists and works in PHP 8.5, but it has been deprecated since PHP 8.1 and raises an E_DEPRECATED notice on every call. Plan to migrate before it is removed.
What should I use instead of strftime?
Use date() for fixed or English formats and IntlDateFormatter::format() when you need localised month and weekday names. For UTC output, gmdate() replaces gmstrftime().
Why does my strftime format work on Linux but not on Windows?
strftime forwards the format to the operating system's C library, and Windows does not implement specifiers such as %e, %T and %D. That inconsistency is a large part of why the function was deprecated.
More examples
Migration map from % codes to date() codes
This prints the date() equivalent of each common strftime specifier with its actual output, which is what you need when rewriting old format strings. Watch the two traps: %M is minutes but date's M is a month name, and %j counts from 1 while date's z counts from 0.
<?php
date_default_timezone_set('UTC');
$ts = mktime(14, 7, 3, 4, 9, 2025);
$map = ['%Y' => 'Y', '%m' => 'm', '%d' => 'd', '%H' => 'H',
'%M' => 'i', '%S' => 's', '%A' => 'l', '%B' => 'F', '%j' => 'z'];
foreach ($map as $old => $new) {
printf("%-4s -> %-2s %s\n", $old, $new, date($new, $ts));
}Localised output the modern way
IntlDateFormatter is the recommended replacement when you need translated month names, and it works from ICU data rather than the host's locale files. The class_exists guard is there because intl is not compiled into every PHP build; date() output is always available as the fallback line.
<?php
date_default_timezone_set('UTC');
$ts = mktime(0, 0, 0, 3, 1, 2026);
if (class_exists('IntlDateFormatter')) {
$fmt = new IntlDateFormatter('fr_FR', IntlDateFormatter::LONG,
IntlDateFormatter::NONE, 'UTC');
echo $fmt->format($ts), "\n";
} else {
echo "intl extension not loaded\n";
}
echo date('j F Y', $ts), "\n";
Discussion