PHP 8.1: strftime() is deprecated - php

When upgrading to PHP 8.1, I got an error regarding "strftime".
How do I correct the code to correctly display the full month name in any language?
$date = strftime("%e %B %Y", strtotime('2010-01-08'))

To my dear and late strftime()... I found a way to adapt with IntlDateFormatter::formatObject and here is the link for the references to the schemas:
https://unicode-org.github.io/icu/userguide/format_parse/datetime/#date-field-symbol-table
... For those who want to format the date more precisely
// "date_default_timezone_set" may be required by your server
date_default_timezone_set( 'Europe/Paris' );
// make a DateTime object
// the "now" parameter is for get the current date,
// but that work with a date recived from a database
// ex. replace "now" by '2022-04-04 05:05:05'
$dateTimeObj = new DateTime('now', new DateTimeZone('Europe/Paris'));
// format the date according to your preferences
// the 3 params are [ DateTime object, ICU date scheme, string locale ]
$dateFormatted =
IntlDateFormatter::formatObject(
$dateTimeObj,
'eee d MMMM y à HH:mm',
'fr'
);
// test :
echo ucwords($dateFormatted);
// output : Jeu. 7 Avril 2022 à 04:56

I've chosen to use php81_bc/strftime composer package as a replacement.
Here the documentation.
Pay attention that the output could be different from native strftime 'cause php81_bc/strftime uses a different library for locale aware formatting (ICU).
Note that output can be slightly different between libc sprintf and this function as it is using ICU.

You can use the IntlDateFormatter class. The class works independently of the locales settings. With a function like this
function formatLanguage(DateTime $dt,string $format,string $language = 'en') : string {
$curTz = $dt->getTimezone();
if($curTz->getName() === 'Z'){
//INTL don't know Z
$curTz = new DateTimeZone('UTC');
}
$formatPattern = strtr($format,array(
'D' => '{#1}',
'l' => '{#2}',
'M' => '{#3}',
'F' => '{#4}',
));
$strDate = $dt->format($formatPattern);
$regEx = '~\{#\d\}~';
while(preg_match($regEx,$strDate,$match)) {
$IntlFormat = strtr($match[0],array(
'{#1}' => 'E',
'{#2}' => 'EEEE',
'{#3}' => 'MMM',
'{#4}' => 'MMMM',
));
$fmt = datefmt_create( $language ,IntlDateFormatter::FULL, IntlDateFormatter::FULL,
$curTz, IntlDateFormatter::GREGORIAN, $IntlFormat);
$replace = $fmt ? datefmt_format( $fmt ,$dt) : "???";
$strDate = str_replace($match[0], $replace, $strDate);
}
return $strDate;
}
you can use format parameters like for datetime.
$dt = date_create('2022-01-31');
echo formatLanguage($dt, 'd F Y','pl'); //31 stycznia 2022
There are extension classes for DateTime that have such functions integrated as methods.
echo dt::create('2022-01-31')->formatL('d F Y','pl');

The strftime is obsolete and DateTime::format() provide a quick replacement and IntlDateFormatter::format() provied a more sophisticated slution.
this links will be help you:
https://github.com/modxcms/revolution/issues/15864
https://github.com/php/php-src/blob/1cf4fb739f7a4fa8404a4c0958f13d04eae519d4/UPGRADING#L379-L381
https://www.php.net/manual/en/datetime.format.php

strftime is deprecated PHP 8.1, You can use date function.
$date = date("%e F Y", strtotime('2010-01-08'))

Hey I have also experienced this issue as well so after some research on PHP's official documentation here what I found!
https://www.php.net/manual/en/function.strftime.php
They are saying that it is depricated and use setlocale() function
this also work same as strftime().
For more information please visit official PHP docs of setlocale() https://www.php.net/manual/en/function.setlocale.php

A quick and simple replacement for the deprecated function strftime can be following.
Instead of using (taking the sample from the question)
$date = strftime("%e %B %Y", strtotime('2010-01-08'))
convert that to:
$date = date('d M Y', strtotime('2010-01-08')

Related

php, how to output date in a fixed locale/language format?

In a php script, I need to output a date in a fixed language, something like $date-> format('j F Y', 'it_IT').
I know that I may use:
setlocale(LC_ALL, 'it_IT');
$dataItalian = strftime("%e %B %Y", strtotime($myDataObj->format('j F Y')));;
But strftime has been deprecated, and I do not see how I am supposed to do otherwise.
(I have php-intl installed).
i think you should use IntlDateFormatter class.
See php manual here -> https://www.php.net/manual/en/class.intldateformatter.php
<?php
function formatDate(Datetime $dateTime, $format = 3, $locale = 3 ): string{
$fmt = new IntlDateFormatter('it_IT', 3, 3, 'Europe/Rome', 1, 'dd/MM/YYYY');
return $fmt->format($dateTime);
}
//an example with Datetime 'now' //
$localZone = new DateTimeZone('Europe/Rome');
$yourDate1 = new Datetime('now', $localZone);
echo formatDate($date1);
i hope that will help you!

Carbon how I can display the day of week in Greek? [duplicate]

Ive read several stackoverflows about set locale. I tested locale -a in the terminal to see if my locale was in there, and it was. The following rule of code is added in the appServiceProvider:
public function boot()
{
Carbon::setLocale($this->app->getLocale());
}
The $this->app->getLocale() returns "nl"
Anyone know why Carbon still shows Sunday instead of Zondag for example?
Translating a carbon date using global localized format
Tested in: Laravel 5.8, Laravel 6, Laravel 8
In config/app.php
'locale' => 'id', // The default is 'en', but this time I want localize them to Indonesian (ID)
Then, to make locale output do something like this:
// WITHOUT LOCALE
Carbon\Carbon::parse('2019-03-01')->format('d F Y'); //Output: "01 March 2019"
now()->subMinute(5)->diffForHumans(); // Output: "5 minutes ago"
// WITH LOCALE
Carbon\Carbon::parse('2019-03-01')->translatedFormat('d F Y'); // Output: "01 Maret 2019"
now()->subMinute(5)->diffForHumans(); // Output: "5 menit yang lalu"
For more information about converting localize dates you can see on below link
https://carbon.nesbot.com/docs/#api-localization
You might want to use setLocale(LC_TIME, $this->app->getLocale()) somewhere at the start of your application.
Then if you wish to have the localized date format with local names use the formatLocalized function
Carbon::now()->formatLocalized('%d %B %Y');
See http://php.net/manual/en/function.strftime.php for parameter for formatting
Researching I have found two alternative options:
$date = Carbon::now();
$date->locale('de')->translatedFormat('d F Y');
and:
$date = Carbon::now();
$carbonDateFactory = new CarbonFactory([
'locale' => 'de_DE',
'timezone' => 'Europe/Paris',
]);
$carbonDateFactory->make($date)->isoFormat('d MMMM YYYY');
and the ISO compatible format symbols are here
I solved this by calling setLocale on multiple classes:
$locale = 'nl_NL';
\Carbon\Carbon::setLocale($locale);
\Carbon\CarbonImmutable::setLocale($locale);
\Carbon\CarbonPeriod::setLocale($locale);
\Carbon\CarbonInterval::setLocale($locale);
\Illuminate\Support\Carbon::setLocale($locale);
There's also this ServiceProvider that does the same.
In your AppServiceProvider's register function:
setlocale(LC_TIME, 'nl_NL.utf8');
Carbon::setLocale(config('app.locale'));
Then use translatedFormat() instead of format() or formatLocalized() which is deprecated.
This uses the date() patern which works like format() but translates the string using the current locale.
read more here and here.
try this : setLocale(LC_TIME, app()->getLocale());

Get day from string in spanish PHP

I'm trying with:
setlocale(LC_ALL,"es_ES");
$string = "24/11/2014";
$date = DateTime::createFromFormat("d/m/Y", $string);
echo $date->format("l");
And I'm getting Monday, which is correct but I need it in spanish, so, is there any way to retrieve this day in spanish?
From the DateTime format page:
This method does not use locales. All output is in English.
If you need locales look into strftime
Example:
setlocale(LC_ALL,"es_ES");
$string = "24/11/2014";
$date = DateTime::createFromFormat("d/m/Y", $string);
echo strftime("%A",$date->getTimestamp());
I use:
setlocale(LC_ALL, "es_ES", 'Spanish_Spain', 'Spanish');
echo iconv('ISO-8859-2', 'UTF-8', strftime("%A, %d de %B de %Y", strtotime($row['date'])));
or
setlocale(LC_ALL,"es_ES#euro","es_ES","esp");
both works. I have to use iconv to avoid strange symbols in accents, and i obtain this result:
domingo, 09 de octubre de 2016
You can use strftime function:
setlocale( LC_ALL,"es_ES#euro","es_ES","esp" );
echo strftime( "%A %d de %B del %Y" );
or
function SpanishDate($FechaStamp)
{
$ano = date('Y',$FechaStamp);
$mes = date('n',$FechaStamp);
$dia = date('d',$FechaStamp);
$diasemana = date('w',$FechaStamp);
$diassemanaN= array("Domingo","Lunes","Martes","Miércoles",
"Jueves","Viernes","Sábado");
$mesesN=array(1=>"Enero","Febrero","Marzo","Abril","Mayo","Junio","Julio",
"Agosto","Septiembre","Octubre","Noviembre","Diciembre");
return $diassemanaN[$diasemana].", $dia de ". $mesesN[$mes] ." de $ano";
}
This is how I did it.
// Define key-value array
$days_dias = array(
'Monday'=>'Lunes',
'Tuesday'=>'Martes',
'Wednesday'=>'Miércoles',
'Thursday'=>'Jueves',
'Friday'=>'Viernes',
'Saturday'=>'Sábado',
'Sunday'=>'Domingo'
);
//lookup dia based on day name
$dia = $days_dias[date('l', strtotime("1993-04-28"))];
strftime has been DEPRECATED as of PHP 8.1.0
Another alternative is using IntlDateFormatter:
$formatter = new \IntlDateFormatter(
'es_ES',
\IntlDateFormatter::LONG,
\IntlDateFormatter::LONG,
'Europe/Madrid' //more in: https://www.php.net/manual/en/timezones.europe.php
);
echo $formatter->formatObject(new \DateTime(), "eeee", "es_ES");
note that "eeee" is a format from ICU
Digging a bit on how to do this, most of the times people use the function strftime.
Unfortunately, the strftime function has been DEPRECATED as of PHP 8.1.0 and 'is highly discouraged' to rely on it.
You have two options:
Use the IntlDateFormatter function, but you need to install the intl extension for php and enable it in your php.ini file. This can be problematic in some shared production environments. The good side is you keep the output masks and if you use other languages you can easily exchange between them.
The code would be like this:
$d = new IntlDateFormatter('es_ES', null, null, null, null, null, 'dd MMMM y');
print($d->format(new DateTime('2022-12-01'));
and the output would be like this 01 Diciembre 2022
Use a handmade function so you can reuse it several times. It is easier and faster to use, but you lose output masks and is tied to a single language.
The code would be like this:
function fechaEspanol($fecha)
{
$format = 'Y-m-d H:i:s'; //This is an optional input format mask for datetime database extracted info
$d = DateTime::createFromFormat($format, $fecha); //A simple $d = new DateTime($fecha) can also be used
$anio = $d->format('Y');
$mes = $d->format('n');
$dia = $d->format('d');
$diasemana = $d->format('w');
$diassemanaN = array("Domingo", "Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sábado");
$mesesN = array(1 => "Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre");
return "{$diassemanaN[$diasemana]}, $dia de {$mesesN[$mes]} de $anio";
}
If fechaEspanol('2022-12-01 12:00:00') the output would be like this 01 Diciembre 2022. This function can be optimized, but is put like this for a clearer view of what is being done.
I hope this helps someone.

date_create_from_format equivalent for PHP 5.2 (or lower)

I'm working with PHP 5.3 on my local machine and needed to parse a UK date format (dd/mm/yyyy). I found that strtotime didn't work with that date format, so I used date_create_from_format instead - which works great.
Now, my problem is that my staging server is running PHP 5.2, and date_create_from_format doesn't work on that version. (It's a shared server, and wouldn't have a clue how to upgrade it to PHP 5.3)
So is there a similar function to date_create_from_format that I can use? Bespoke or PHP native?
If strptime is not available to you, then here is a different idea. It is similar to Col. Shrapnel's approach but instead uses sscanf to parse the date-part values into variables and uses those to construct a new DateTime object.
list($day, $month, $year) = sscanf('12/04/2010', '%02d/%02d/%04d');
$datetime = new DateTime("$year-$month-$day");
echo $datetime->format('r');
Try strptime() which is available in PHP 5.1 and above.
include this code:
function DEFINE_date_create_from_format()
{
function date_create_from_format( $dformat, $dvalue )
{
$schedule = $dvalue;
$schedule_format = str_replace(array('Y','m','d', 'H', 'i','a'),array('%Y','%m','%d', '%I', '%M', '%p' ) ,$dformat);
// %Y, %m and %d correspond to date()'s Y m and d.
// %I corresponds to H, %M to i and %p to a
$ugly = strptime($schedule, $schedule_format);
$ymd = sprintf(
// This is a format string that takes six total decimal
// arguments, then left-pads them with zeros to either
// 4 or 2 characters, as needed
'%04d-%02d-%02d %02d:%02d:%02d',
$ugly['tm_year'] + 1900, // This will be "111", so we need to add 1900.
$ugly['tm_mon'] + 1, // This will be the month minus one, so we add one.
$ugly['tm_mday'],
$ugly['tm_hour'],
$ugly['tm_min'],
$ugly['tm_sec']
);
$new_schedule = new DateTime($ymd);
return $new_schedule;
}
}
if( !function_exists("date_create_from_format") )
DEFINE_date_create_from_format();
If you need to parse only one particular format, it's elementary string operation.
list($d,$m,$y)=explode("/",$datestr);
use format DD-MM-YY and timestamp, I think it will be easier for you
$date="31-11-2015";
$timestamp=strtotime($date);
$dateConvert=date('d-m-Y', $timestamp);
echo $dateConvert;
I've used it

Date function output in a local language [duplicate]

This question already has answers here:
Formatting DateTime object, respecting Locale::getDefault()
(6 answers)
Closed 1 year ago.
I am trying to output dates in the Italian format using date() as follows:
<?php
setlocale(LC_ALL, 'it_IT');
echo date("D d M Y", $row['eventtime']);
?>
However, it is still coming out in the English format. What else could I do? Is there something wrong?
The solution has to be script specific and not server-wide.
date() is not locale-aware. You should use strftime() and its format specifiers to output locale-aware dates (from the date() PHP manual):
To format dates in other languages,
you should use the setlocale() and
strftime() functions instead of
date().
Regarding Anti Veeranna's comment: he is absolutely right, since you have to be very careful with setting locales as they are sometimes not limited to the current script scope. The best way would be:
$oldLocale = setlocale(LC_TIME, 'it_IT');
echo utf8_encode( strftime("%a %d %b %Y", $row['eventtime']) );
setlocale(LC_TIME, $oldLocale);
I found that setlocale isn't reliable, as it is set per process, not per thread (the manual mentions this). This means other running scripts can change the locale at any time. A solution is using IntlDateFormatter from the intl php extension.
$fmt = new \IntlDateFormatter('it_IT', NULL, NULL);
$fmt->setPattern('d MMMM yyyy HH:mm');
// See: http://userguide.icu-project.org/formatparse/datetime for pattern syntax
echo $fmt->format(new \DateTime());
If it doesn't work you might need to:
Install intl php extension (ubuntu example): sudo apt-get install php5-intl
Install the locale you want to use: sudo locale-gen it_IT
it_IT locale has to be installed/enabled by your server admin, otherwise this will not work.
So, Jonathan's solution is probably the best.
About the article on http://www.phpnews.it/articoli/ottenere-date-in-italiano/response, the blog suggest an alternative method, but the code is not working, here is the correct code:
function timestamp_to_date_italian($date)
{
$months = array(
'01' => 'Gennaio',
'02' => 'Febbraio',
'03' => 'Marzo',
'04' => 'Aprile',
'05' => 'Maggio',
'06' => 'Giugno',
'07' => 'Luglio',
'08' => 'Agosto',
'09' => 'Settembre',
'10' => 'Ottobre',
'11' => 'Novembre',
'12' => 'Dicembre');
list($day, $month, $year) = explode('-',date('d-m-Y', $date));
return $day . ' ' . $months[$month] . ' ' . $year;
}

Categories