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'));
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'));
Hello i have 2 variables for month and year. I would like to display month name in my language but i dont manage to make it working. Here is my code
setlocale(LC_TIME, array('ro.utf-8', 'ro_RO.UTF-8', 'ro_RO.utf-8', 'ro', 'ro_RO', 'ro_RO.ISO8859-2'));
$luna=$_GET['month'];
$an=$_GET['year'];
$dateObj = DateTime::createFromFormat('!m', $luna);
$monthName = $dateObj->format('F');
$data='Arhiva '.$monthName.' - '.$an.'';
it displays June 2014 and i want Iunie 2014 June=Iunie in my country. The month given by link is dinamic and it can be any number.
You can use strftime (http://php.net/manual/en/function.strftime.php):
setlocale(LC_TIME, array('ro.utf-8', 'ro_RO.UTF-8', 'ro_RO.utf-8', 'ro', 'ro_RO', 'ro_RO.ISO8859-2'));
$luna=$_GET['month'];
$an=$_GET['year'];
$dateObj = DateTime::createFromFormat('!m', $luna);
$monthName = strftime('%B', $dateObj->getTimestamp());
$data='Arhiva '.$monthName.' - '.$an.'';
You can convert with IntlDateFormatter function
$dateObj = DateTime::createFromFormat('!m', $luna);
$formatter = new IntlDateFormatter("ro_RO",
IntlDateFormatter::FULL,
IntlDateFormatter::FULL,
'Europe/Bucharest',
IntlDateFormatter::GREGORIAN,
'MMMM');
echo $formatter->format($dateObj).' - '.$an; // Iunie - 2014
Try This
setlocale(LC_TIME, 'fr_FR');
$monthName = strftime("%B",mktime(0, 0, 0, $_GET['month']));
echo $monthName ; //It outputs month name in your local language that you have set in 'setlocale'
In this case it is set to French. Similarly you can use it for your locale by passing your language code like:
sr_BA - Serbian (Montenegro);
sr_CS - Serbian (Serbia);
sr_ME - Serbian (Serbia and Montenegro);
Happy coding!!
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().
Since PHP uses data from ICU in the intl extension, are there ways to get localized month names from within PHP?
While I can get the data from ICU's xml files and extract them into my own set of files, I would much prefer a clean and easier solution if possible.
Finally, are there ways to get the date format (MM/DD/YYYY or DD/MM/YYYY), given the locale from the intl extension?
Not sure what you need the month names for, but if you just want to use translated names for months, strftime() uses the names according to the current locale (use the %B modifier).
If you want a list of month names for some other use you can use strftime() for that too:
$months = array();
for( $i = 1; $i <= 12; $i++ ) {
$months[ $i ] = strftime( '%B', mktime( 0, 0, 0, $i, 1 ) );
}
For the second question there might be a native function for it but it's not hard to make one yourself:
$currentDate = strftime( '%x', strtotime( '2011-12-13' ) );
$localFormat = str_replace(
array( '13', '12', '2011', '11' ),
array( 'DD', 'MM', 'YYYY', 'YY' ),
$currentDate
);
Could you use IntlDateFormatter::getPattern to get the pattern? I don't know about strftime, but I would use the suggestion of formatting with a pattern MMMM to get the month name, through each month. Looks like php.intl doesn't expose the data directly.
(This is not a real answer, it would be a comment to Steven R. Loomis' answer. I write it only because I can't format code in comments)
Thank you Steven R. Loomis, this is my solution:
function local_month_name($locale, $monthnum)
{
/**
* Return the localized name of the given month
*
* #author Lucas Malor
* #param string $locale The locale identifier (for example 'en_US')
* #param int $monthnum The month as number
* #return string The localized string
*/
$fmt = new IntlDateFormatter($locale, IntlDateFormatter::LONG,
IntlDateFormatter::NONE);
$fmt->setPattern('MMMM');
return $fmt->format(mktime(0, 0, 0, $monthnum, 1, 1970));
}
For English or other languages that does not use declination it will work fine, but for all of them that use declination the output will not be valid.
For Polish i.e. the output for March will be marca instead of marzec
For Russian i.e. the output for March will be Мартa instead of Март
This method will not work through ALL languages which most probably is required and may not be easily tested by person not speaking the language.
If you only need names of the months it is better to use:
setlocale(LC_TIME, 'pl_PL');
$month_name = strftime('%B', mktime(0, 0, 0, $month_number));
Please have in mind that locale change may impact other parts of your application.
setlocale(LC_ALL, 'en_US.ISO_8859-1');
and so on
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");