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.
Related
I have this part of the function, which gives me name of the months in English. How can I translate them to my local language (Serbian)?
$month_name = date('F', mktime(0, 0, 0, $i));
Where $i is the number of the month (values 1 - 12). See also PHP:mktime.
You should use setlocale():
setlocale(LC_TIME, 'fr_FR');
$month_name = date('F', mktime(0, 0, 0, $i));
In this case it would set it to French. For your case it should be one of the following:
sr_BA - Serbian (Montenegro)
sr_CS - Serbian (Serbia)
sr_ME - Serbian (Serbia and Montenegro)
You should use setlocale() and strftime():
setlocale(LC_TIME, 'sr_CS');
$month_name = strftime('%B', mktime(0, 0, 0, $i));
Here is an example with IntlDateFormatter
$format = new IntlDateFormatter('sr_CS', IntlDateFormatter::NONE,
IntlDateFormatter::NONE, NULL, NULL, "MMM");
$monthName = datefmt_format($format, mktime(0, 0, 0, $i));
For all who struggle with German (and de_DE), make sure you are using the right language code. Login to your server and run locale -a to see a list of all available ones. For me it shows:
CC.UTF-8de_AT.utf8de_BE.utf8de_CH.utf8de_DE.utf8de_LI.utf8de_LU.utf8...
You need to use one of those codes.
Then you can use:
date_default_timezone_set('Europe/Berlin');
setlocale(LC_ALL, 'de_DE.utf8');
$date_now = date('Y-m-d');
$month_available = strftime('%B %Y', strtotime($date_now));
$month_next = strftime('%B %Y', strtotime($date_now.' +1 month'));
and "März 2020" etc. get displayed correctly.
This question asks how to get a list of months, I only see hints, not a complete code answer so:
If you have IntlDateFormatter available - which is available in most of the cases, you can create a formatter in a given locale and repeatedly push a date to it created just based on month number
// or any other locales like pl_PL, cs_CZ, fr_FR, zh, zh_Hans, ...
$locale = 'en_GB';
$dateFormatter = new IntlDateFormatter(
$locale,
IntlDateFormatter::LONG, // date type
IntlDateFormatter::NONE // time type
);
$dateFormatter->setPattern('LLLL'); // full month name with NO DECLENSION ;-)
$months_locale = [];
for ($month_number = 1; $month_number <= 12; ++$month_number) {
$months_locale[] = $dateFormatter->format(
// 'n' => month number with no leading zeros
DateTime::createFromFormat('n', (string)$month_number)
);
}
// test output
echo "<pre>";
var_dump($months_locale);
echo "</pre>";
Note: LLLL takes care of not-declining, but it does not take care of the lowercase/uppercase of the first letter if the languages has such things.Good example is that you can get January for en_GB but leden for cs_CZ
If you want all letters lowercase => use mb_strtolower($month_name); - docs
If you want just the FIRST letter to be upper case =>
=> use mb_convert_case($month_name, MB_CASE_TITLE, 'UTF-8'); - docs
Always use mb_* functions or their variations for locale-originating strings !
So no, don't use ucfirst !
It is good idea to pass the encoding when setting the locale:
<?php
date_default_timezone_set('Europe/Belgrade');
setlocale(LC_TIME, array('sr_CS.UTF-8', 'sr.UTF-8'));
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!
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')
I have a function that reads out the date in a file on the first line. This date is formatted in dutch like this 2 mei 2013 or 28 jun. 2013
It needs to convert the date string into a timestamp, but whatever i try it won't work for the mei moths or any other dutch named month. Here is the code I currently have (the original function is a bit more code, but this is where it goes wrong)
function getTimestamp($date){
date_default_timezone_set('Europe/Amsterdam');
setlocale(LC_ALL, 'nl_NL');
$timestamp = strtotime($date);
return $timestamp;
}
Now, here are some results when using this function:
$timestamp = getTimestamp('28 jun. 2013') //1372370400
$timestamp2 = getTimestamp('2 mei 2013') // false
but, when i put this code in the function
echo strftime('%e %b %Y', 1367445600)."\n";
it prints '2 mei 2013'
How can I tell php not only format the date-time string in Dutch, but also read it in Dutch?
=======================
Thanks to some explanation below I now have the code working (this is the full function)
public function getReportDate(){
$mothsTranslated = array('mrt'=> 'mar','mei'=>'may', 'okt'=>'oct');
$content = file($this->file);
$line = $content[0];
$header = str_getcsv($line, $this->delimiter);
$date = str_replace('.', '', $header[1]);
foreach ($mothsTranslated as $dutch => $eng) {
if(strpos($date, $dutch) !== false){
$date = str_replace($dutch, $eng, $date);
}
}
$timestamp = strtotime($date);
return $timestamp;
}
Without creating your own date parser, the native PHP functions only use English dates.
However, there is an international dateformatter extension available for PHP. You can install this plugin and then would be able to parse non-english dates.
http://www.php.net/manual/en/intldateformatter.parse.php
As others found out, strtotime does not respect the set locale.
Indeed, it's description in the manual states: "Parse about any English textual datetime description into a Unix timestamp"
Solutions
You can use strptime() since PHP5 that does respect the locale (like strftime), but there are some warnings about using it on the php website.
You could write a function that replaces the Dutch month names to English month names and then calls strtotime.
I have this part of the function, which gives me name of the months in English. How can I translate them to my local language (Serbian)?
$month_name = date('F', mktime(0, 0, 0, $i));
Where $i is the number of the month (values 1 - 12). See also PHP:mktime.
You should use setlocale():
setlocale(LC_TIME, 'fr_FR');
$month_name = date('F', mktime(0, 0, 0, $i));
In this case it would set it to French. For your case it should be one of the following:
sr_BA - Serbian (Montenegro)
sr_CS - Serbian (Serbia)
sr_ME - Serbian (Serbia and Montenegro)
You should use setlocale() and strftime():
setlocale(LC_TIME, 'sr_CS');
$month_name = strftime('%B', mktime(0, 0, 0, $i));
Here is an example with IntlDateFormatter
$format = new IntlDateFormatter('sr_CS', IntlDateFormatter::NONE,
IntlDateFormatter::NONE, NULL, NULL, "MMM");
$monthName = datefmt_format($format, mktime(0, 0, 0, $i));
For all who struggle with German (and de_DE), make sure you are using the right language code. Login to your server and run locale -a to see a list of all available ones. For me it shows:
CC.UTF-8de_AT.utf8de_BE.utf8de_CH.utf8de_DE.utf8de_LI.utf8de_LU.utf8...
You need to use one of those codes.
Then you can use:
date_default_timezone_set('Europe/Berlin');
setlocale(LC_ALL, 'de_DE.utf8');
$date_now = date('Y-m-d');
$month_available = strftime('%B %Y', strtotime($date_now));
$month_next = strftime('%B %Y', strtotime($date_now.' +1 month'));
and "März 2020" etc. get displayed correctly.
This question asks how to get a list of months, I only see hints, not a complete code answer so:
If you have IntlDateFormatter available - which is available in most of the cases, you can create a formatter in a given locale and repeatedly push a date to it created just based on month number
// or any other locales like pl_PL, cs_CZ, fr_FR, zh, zh_Hans, ...
$locale = 'en_GB';
$dateFormatter = new IntlDateFormatter(
$locale,
IntlDateFormatter::LONG, // date type
IntlDateFormatter::NONE // time type
);
$dateFormatter->setPattern('LLLL'); // full month name with NO DECLENSION ;-)
$months_locale = [];
for ($month_number = 1; $month_number <= 12; ++$month_number) {
$months_locale[] = $dateFormatter->format(
// 'n' => month number with no leading zeros
DateTime::createFromFormat('n', (string)$month_number)
);
}
// test output
echo "<pre>";
var_dump($months_locale);
echo "</pre>";
Note: LLLL takes care of not-declining, but it does not take care of the lowercase/uppercase of the first letter if the languages has such things.Good example is that you can get January for en_GB but leden for cs_CZ
If you want all letters lowercase => use mb_strtolower($month_name); - docs
If you want just the FIRST letter to be upper case =>
=> use mb_convert_case($month_name, MB_CASE_TITLE, 'UTF-8'); - docs
Always use mb_* functions or their variations for locale-originating strings !
So no, don't use ucfirst !
It is good idea to pass the encoding when setting the locale:
<?php
date_default_timezone_set('Europe/Belgrade');
setlocale(LC_TIME, array('sr_CS.UTF-8', 'sr.UTF-8'));