Date function output in a local language [duplicate] - php

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;
}

Related

PHP 8.1: strftime() is deprecated

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')

PHP strptime() Doesn't seem to work? I can't see anything wrong

I am currently trying to get a database transfered from an old system to a new one, and i have run into a small issue.
I have a db row formatted at:
2007-04-24 00:23:59
(yyyy-mm-dd hh:mm:ss)
And i cant seem to get it to work through strptime()
Here is what i have:
$format = '%Y-%m-%d %H:%i:%s';
$ct = strptime($row['time'], $format );
//$row['time'] == 2007-01-11 00:47:27
This returns nothing.
Can anyone see anything wrong with that?
Thanks.
Format should be a bit different:
$format = '%Y-%m-%d %H:%M:%S'; // or just '%F %T'
Here's the corresponding section of strftime format documentation:
%M Two digit representation of the minute [00 through 59]
%S Two digit representation of the second [00 through 59]
%T Same as "%H:%M:%S"
%F Same as "%Y-%m-%d" (commonly used in database datestamps)
Refer to the strftime() documentation for the proper format.
Your foramt should be:
$format = '%Y-%m-%d %T';
From manual http://www.php.net/manual/en/function.strptime.php
<?php
$format = '%d/%m/%Y %H:%M:%S';
$strf = strftime($format);
echo "$strf\n";
print_r(strptime($strf, $format));
?>
Result
03/10/2004 15:54:19
Array
(
[tm_sec] => 19
[tm_min] => 54
[tm_hour] => 15
[tm_mday] => 3
[tm_mon] => 9
[tm_year] => 104
[tm_wday] => 0
[tm_yday] => 276
[unparsed] =>
)
strptime() is not available in Windows.
Note: This function is not implemented on Windows platforms.
Source: http://php.net/manual/en/function.strptime.php
This is how I usually handle date formatting.
$somedate = strtotime($dateValue);
$formatted_date = date('Y-m-d H:i:s', $somedate);

php function to convert "04-05-2012" to "04/05/2012?

I have tried using date("m/d/Y", strtotime("04-05-2012")) but I will get "05/04/2012" or on some other dates for example "03-30-2012" I will get "12/31/1969" (which makes sense because it it mixing up the month and day and there is no 30th month. So how should I do this? I also want to then convert the value into a UNIX time so that I can search it against MySQL db.
You can use the DateTime object and createFromFormat static method to do it :
$date = DateTime::createFromFormat('m-d-Y',"03-30-2012");
$date->format('m/d/Y');
If you know for certain that the format you start with is DD-MM-YYY when why not use a simple replace?
e.g. $newDate = str_replace('-', '/', '04-05-2012');
One way to do it would be using explode() and mktime():
$inDate = '03-30-2012';
list($m, $d, $y) = explode('-', $inDate);
$outDate = date('m/d/Y', mktime(0, 0, 0, $m, $d, $y));
This assumes the format is somehow dynamic, though. Otherwise, str_replace() is your best option, as others pointed out.
This isn't so much a date format question as a string manipulation question.
But it's still good to know that strtotime() exists.
[ghoti#pc ~]$ cat transdate.php
#!/usr/local/bin/php
<?php
$olddate = "04-05-2012"; // assuming mm-dd-YYYY
// Get the date parts into an array
$parts = explode("-", $olddate);
// Switch to YYYY-mm-dd, which will be interpreted consistently
$neworder = sprintf("%s-%s-%s", $parts[2], $parts[0], $parts[1]);
printf("New order: %s\n", $neworder);
// Set your timezone, or PHP will whine and complain
date_default_timezone_set('America/Toronto');
// Convert your reordered date to an epoch second (unix timestamp)
$epoch = strtotime($neworder);
// At a terminal, `man strftime` (or read the PHP function's docs) for details.
print "Alternate formats:\n";
printf("\t%s\n", strftime("%D", $epoch));
printf("\t%s\n", strftime("%F", $epoch));
printf("\t%s\n", strftime("%A %B %e, %Y (week %U)", $epoch));
[ghoti#pc ~]$ ./transdate.php
New order: 2012-04-05
Alternate formats:
04/05/12
2012-04-05
Thursday April 5, 2012 (week 14)
[ghoti#pc ~]$
This will work in PHP 5.1.6. Heck, it should work in PHP 4, except for date_default_timezone_set().

strtotime With Different Languages?

Does strtotime only work in the default language on the server? The below code should resolve to august 11, 2005, however it uses the french "aout" instead of the english "aug".
Any ideas how to handle this?
<?php
$date = strtotime('11 aout 05');
echo date('d M Y',$date);
?>
As mentioned strtotime does not take locale into account. However you could use strptime (see http://ca1.php.net/manual/en/function.strptime.php), since according to the docs:
Month and weekday names and other language dependent strings respect the current locale set with setlocale() (LC_TIME).
Note that depending on your system, locale and encoding you will have to account for accented characters.
French month dates are:
janvier février mars avril mai juin juillet août septembre octobre
novembre décembre
Hence, for the very specific case where months are in French you could use
function myStrtotime($date_string) { return strtotime(strtr(strtolower($date_string), array('janvier'=>'jan','février'=>'feb','mars'=>'march','avril'=>'apr','mai'=>'may','juin'=>'jun','juillet'=>'jul','août'=>'aug','septembre'=>'sep','octobre'=>'oct','novembre'=>'nov','décembre'=>'dec'))); }
The function anyway does not break if you pass $date_string in English, because it won't do any substitution.
From the docs
Parse about any English textual datetime description into a Unix
timestamp
Edit: Six years down the road now, and what was meant to be a side-note about why strtotime() was an inappropriate solution for the issue at hand became the accepted answer 😲
To better answer the actual question I want to echo Marc B's answer: despite the downvotes, date_create_from_format, paired with a custom Month interpreter will provide the most reliable solution
However it appears that there is still no silver-bullet for international date parsing built-in to PHP for the time being.
This method should work for you using strftime:
setlocale (LC_TIME, "fr_FR.utf8"); //Setting the locale to French with UTF-8
echo strftime(" %d %h %Y",strtotime($date));
strftime
I wrote a simple function partially solves this problem.
It does not work as a full strtotme(), but it determines the number of months names in the dates.
<?php
// For example, I get the name of the month from a
// date "1 January 2015" and set him (with different languages):
echo month_to_number('January').PHP_EOL; // returns "01" (January)
echo month_to_number('Января', 'ru_RU').PHP_EOL; // returns "01" (January)
echo month_to_number('Мая', 'ru_RU').PHP_EOL; // returns "05" (May)
echo month_to_number('Gennaio', 'it_IT').PHP_EOL; // returns "01" (January)
echo month_to_number('janvier', 'fr_FR').PHP_EOL; // returns "01" (January)
echo month_to_number('Août', 'fr_FR').PHP_EOL; // returns "08" (August)
echo month_to_number('Décembre', 'fr_FR').PHP_EOL; // returns "12" (December)
Similarly, we can proceed to determine the numbers and days of the week, etc.
Function:
<?php
function month_to_number($month, $locale_set = 'ru_RU')
{
$month = mb_convert_case($month, MB_CASE_LOWER, 'UTF-8');
$month = preg_replace('/я$/', 'й', $month); // fix for 'ru_RU'
$locale =
setlocale(LC_TIME, '0');
setlocale(LC_TIME, $locale_set.'.UTF-8');
$month_number = FALSE;
for ($i = 1; $i <= 12; $i++)
{
$time_month = mktime(0, 0, 0, $i, 1, 1970);
$short_month = date('M', $time_month);
$short_month_lc = strftime('%b', $time_month);
if (stripos($month, $short_month) === 0 OR
stripos($month, $short_month_lc) === 0)
{
$month_number = sprintf("%02d", $i);
break;
}
}
setlocale(LC_TIME, $locale); // return locale back
return $month_number;
}
The key to solving this question is to convert foreign textual representations to their English counterparts. I also needed this, so inspired by the answers already given I wrote a nice and clean function which would work for retrieving the English month name.
function getEnglishMonthName($foreignMonthName,$setlocale='nl_NL'){
setlocale(LC_ALL, 'en_US');
$month_numbers = range(1,12);
foreach($month_numbers as $month)
$english_months[] = strftime('%B',mktime(0,0,0,$month,1,2011));
setlocale(LC_ALL, $setlocale);
foreach($month_numbers as $month)
$foreign_months[] = strftime('%B',mktime(0,0,0,$month,1,2011));
return str_replace($foreign_months, $english_months, $foreignMonthName);
}
echo getEnglishMonthName('juli');
// Outputs July
You can adjust this for days of the week aswell and for any other locale.
Adding this as an extended version of Marco Demaio answer. Added french days of the week and months abbreviations:
<?php
public function frenchStrtotime($date_string) {
$date_string = str_replace('.', '', $date_string); // to remove dots in short names of months, such as in 'janv.', 'févr.', 'avr.', ...
return strtotime(
strtr(
strtolower($date_string), [
'janvier'=>'jan',
'février'=>'feb',
'mars'=>'march',
'avril'=>'apr',
'mai'=>'may',
'juin'=>'jun',
'juillet'=>'jul',
'août'=>'aug',
'septembre'=>'sep',
'octobre'=>'oct',
'novembre'=>'nov',
'décembre'=>'dec',
'janv'=>'jan',
'févr'=>'feb',
'avr'=>'apr',
'juil'=>'jul',
'sept'=>'sep',
'déc'=>'dec',
'lundi' => 'monday',
'mardi' => 'tuesday',
'mercredi' => 'wednesday',
'jeudi' => 'thursday',
'vendredi' => 'friday',
'samedi' => 'saturday',
'dimanche' => 'sunday',
]
)
);
}
It's locale dependent. If it had to check every language for every parse, it'd take nigh-on FOREVER to parse even the simplest of date strings.
If you've got a string with known format, consider using date_create_from_format(), which'll be far more efficient and less error-print
Try to set the locale before conversion:
setlocale(LC_TIME, "fr_FR");

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

Categories