Localize current time in PHP - php

Trying to display current time with PHP (using this):
$date = date('m/d/Y h:i:s a', time());
echo $date;
As simple as it gets. How do I localize it? I want to translate the months and days to Hebrew.
Thanks.

Zend_Date is completely internationalized. You should check that out for a simple way to do it:
All full and abbreviated names of
months and weekdays are supported for
more than 130 languages. Methods
support both input and the output of
dates using the localized names of
months and weekdays, in the
conventional format associated with
each locale.

Actually, I don't think it is quite possible in PHP 5.2 :-(
At least, not with what's bundled with/in PHP (There are libraries coded in PHP that you could use, though, like other answers pointed out)
With PHP 5.3, though, you have the IntlDateFormatter class, which does exactly what you want :
This class represents the ICU date
formatting functionality. It allows
users to display dates in a localized
format or to parse strings into PHP
date values using pattern strings
and/or canned patterns.
For instance, using that class, like this :
echo IntlDateFormatter::create('fr_FR', IntlDateFormatter::FULL, IntlDateFormatter::FULL)->format(time(time())) . "\n";
echo IntlDateFormatter::create('fr_FR', IntlDateFormatter::MEDIUM, IntlDateFormatter::SHORT)->format(time(time())) . "\n";
echo IntlDateFormatter::create('zh-Hant-TW', IntlDateFormatter::FULL, IntlDateFormatter::FULL)->format(time(time())) . "\n";
echo IntlDateFormatter::create('zh-Hant-TW', IntlDateFormatter::MEDIUM, IntlDateFormatter::SHORT)->format(time(time())) . "\n";
echo IntlDateFormatter::create('en_US', IntlDateFormatter::FULL, IntlDateFormatter::FULL)->format(time(time())) . "\n";
echo IntlDateFormatter::create('en_US', IntlDateFormatter::MEDIUM, IntlDateFormatter::SHORT)->format(time(time())) . "\n";
You'd get :
dimanche 9 novembre 2008 23:54:47 GMT+00:00
9 nov. 2008 23:54
2008年11月9日星期日 下午11時54分47秒 GMT+00:00
2008/11/9 下午 11:54
Sunday, November 9, 2008 11:54:47 PM GMT+00:00
Nov 9, 2008 11:54 PM
Which looks quite nice, doesn't it ?
Sad thing is PHP 5.3 is only a few months old, and not available on many hosting services... And will require testing (and probably fixes) for your application...
Thinking about it : maybe you can install the PECL intl extension on PHP 5.2, though, and get the same functionnality...

If you need a more simple way than Zend_Date and IntlDateFormatter try the standard strftime function in php. Here's the stuff I did to get it up and running with the Russian language running php 5.3 on Ubuntu (Russian locale was not installed).
To install locale
cd /usr/share/locales
sudo ./install-language_pack ru_RU
sudo dpkg-reconfigure locales
Restart Apache
Next, use the following php snippet:
setlocale(LC_TIME, 'ru_RU.UTF-8');
echo strftime('%A', time());
Should output today's day of the week.

Related

IntlDateFormatter php japanese year convertion return false for 2019

I want to convert
令和元年8月 = 2019年8月
Ref https://www.conservapedia.com/Japanese_dates
Here I get these
For this I tried code like below here "平成31年8月" returning 2019 but according to ref it should 令和元年8月
Please suggest me is there any solution so I can set my code like reference..
$formatter = new IntlDateFormatter(
'ja_JP#calendar=japanese',
IntlDateFormatter::FULL,
IntlDateFormatter::FULL,
'Europe/Madrid',
IntlDateFormatter::TRADITIONAL,
'Gy年M月'
);
$ts = $formatter->parse('令和元年8月');
//$ts = $formatter->parse('平成31年8月');
var_dump($ts, date('Y-m', $ts));
___FIDDLE___
There seem to be two issues.
Japanese era system does not switch by year, but by a date in a year
平成(Heisei) ended at 2019-04-30, 令和(Reiwa) began at 2019-05-01, so the year-to-year table you referred is not complete if you need to convert specific date in a switching year such like 2019.
For example, both January 平成31 and December 令和1 are AD 2019. So when you only convert year part, they would show the same result.
PHP does not always have up-to-date table inside
On my local, "$formatter->parse('令和元年8月');" returned me 1970-01, the Unix epoch time probably coming from null value. This happens because my using PHP yet does not know that Japanese era changed to 令和.
IntlDateFormatter is in pecl php_intl extension, which calls ICU library. ICU library supports the new era name 令和 at its verion 64.2.
You may check your phpinfo() with "ICU version" and if that is smaller than 64.2, it won't convert 令和 properly.
$ php --info | grep "ICU version"
ICU version => 61.1
If you can not find 64.2+ on your latest available PHP, you may have to compile intl extension with later ICU library yourself.

Php mysql date in table

I have a date field in my table material
id: int;
dat_operation : date;
name : varchar(255);
I would like to know how to translate date format in French
I tried with:
<?php echo date("F j Y",strtotime($var['date_operation']));?>
But i have this result
June 14 2016
First, you'll have to set the "locale information", to specify which language you want to use. Keep in mind, that even though you set that language, it needs to be installed on the server you're running on. It most likely is, but you'll notice if the setlocale has no effect (default is English).
The second thing you'll need to know, is that date() isn't affected by this, you'll have to use strftime() instead, which has a slightly different formatting, which you'll find on the documentation.
An example of using French dates with these two functions:
setlocale(LC_ALL, 'fr_FR');
echo strftime("%B %e %Y", strtotime($var['date_operation']));
Reference and documentation:
http://php.net/manual/en/function.setlocale.php
http://php.net/manual/en/function.strftime.php
The modern and rock-solid approach is the intl (from "Internationalization") extension, which offers e.g. the IntlDateFormatter class:
$date = new DateTime('2016-06-14');
$fmt = new IntlDateFormatter('fr_FR', IntlDateFormatter::LONG, IntlDateFormatter::NONE, 'Europe/Paris', IntlDateFormatter::GREGORIAN);
var_dump($fmt->format($date));
string(12) "14 juin 2016"
If you think it's overkill for your project, you can use the legacy strftime() function but you need to change current locale:
$date = strtotime('2016-06-14');
var_dump(setlocale(LC_TIME, 'fr_FR', 'fr')); // Need to try values until you get true
var_dump(strftime('%B %e %Y', $date));
You need to have French locale data installed. In my experience, this works better on Unix-like systems than on Windows.

PHP date format with intl-aware day suffix?

Sorry if this is a dupe - lots of similar questions but obviously if I could find an exact answer I wouldn't be asking :)
Note I'm coming from .Net and am a PHP newbie, so there may be noob-scale errors.
I would like to be able to output e.g. new DateTime('2014-01-01 13:15:00') as:
'Wednesday the 1st of January 2014 at 1:15PM' (possible - non-localized) or 'Mercredi 1er Janvier 2014 à 13h15' (not possible?).
Basically, there seems to be no ISO formatting equivalent to PHP's 'S' date format specifier, nor is there one for strftime?
The IntlDateFormatter::FULL comes close - but 'Wednesday, 1 January' or 'mercredi 1 janvier' is not good English (or French) - but it seems to be the closest that I can get? I could live without the 'on', 'the' and 'at' if I had to, but ordinal suffixes would be nice. ('Wednesday one January' - what's that, the beginning to a poem?)
I did see one example on the strftime section comments on PHP.net addressing this issue (which seems to suggest that it is an issue) - however it only seemed to add the English suffixes, which didn't seem much use? I'd like a simple method that takes a UTC datetime, a locale and a timezone and outputs a localized string - preferably in 'proper' human-readable format (as above) as is possible in English. I'd like to achieve this without writing a format string for every language in the world. It would also be nice if it worked on my Windows dev box as well as the *nix production box.
<?php
$utcdate = new DateTime('2014-01-01 13:15:00', new DateTimeZone('UTC'));
echo $utcdate->format('l \t\h\e jS \o\f F Y \a\t g:ia') . "<br>";
function dumpDates($date, $locale, $tz){
$date->setTimeZone(new DateTimeZone($tz));
$fmt = new IntlDateFormatter( $locale, IntlDateFormatter::FULL, IntlDateFormatter::FULL,
$tz, IntlDateFormatter::GREGORIAN );
echo $fmt->format($date) . "<br>";
// doesn't work under windows?
setLocale(LC_TIME, $locale);
echo strftime('%A, %#d %B %Y %I:%M:%S %p', $date->getTimeStamp()) . "<br>";
}
dumpDates($utcdate, 'en_GB', 'Europe/London');
dumpDates($utcdate, 'de_DE', 'Europe/Berlin');
dumpDates($utcdate, 'fr_FR', 'Europe/Paris');
?>
The full part of this question - including full grammatical legibility - would be very difficult to do without either, as you say, writing a format string for every language in the world, or finding a library that contains such strings. MomentJs seems to provide great intl support, but after a cursory search, I haven't been able to find a PHP equivalent, other than the intl extension.
You could get to the stage of providing an internationalised form including ordinal-based number by using a combination of IntlDateFormatter and NumberFormatter, by first using NumberFormatter to get the pattern for the date's ordinal suffix/prefix:
$numFmt = new NumberFormatter('fr_FR', NumberFormatter::ORDINAL);
$ordinalDay = $numFmt->format($date->format('j'));
You could then create a IntlDateFormatter that allows you to retrieve the pattern for the Full date format of the target language:
$dateFormat = new IntlDateFormatter('fr_FR', IntlDateFormatter::FULL, IntlDateFormatter::FULL, $tz, IntlDateFormatter::GREGORIAN);
$datePattern = $dateFormat->getPattern();
Finally, you would need to replace the section in the $datePattern representing the day with the escaped ordinal day pattern:
$datePattern = preg_replace('/d+', "'"+$ordinalDay+"'", $datePattern);
$dateFormat->setPattern($datePattern);
$outputDate = $dateFormat->format($date);
Note that the pattern used by IntlDateFormatter is different from the usual PHP date formatting format codes, here is the documentation for the codes recognised.
A warning; in internationalised formats that are fairly rigidly standardized, an ordinal number would look out of place. For example in chinese, the format is:
y年M月d日EEEE
and inserting the ordinal prefix that exists for written Chinese before the day value may look odd to a Chinese reader.

Change the language for date in php

I have this MySQL query, which returns two dates (which are both formatted as a-m-Y). Now I want to translate this date into my own language (Danish). How can I do that.
I have tried both the setlocale() and strftime() functions, but it won't work.
I know it's a very basic question, but i really need help :) Thanks a lot!
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.
Install intl if necesarry (ubuntu): sudo apt-get install php5-intl
Install the locale you want to use (I'm using italian as an example): sudo locale-gen it_IT
Generate a locally formatted date:
$fmt = new \IntlDateFormatter('it_IT', NULL, NULL);
$fmt->setPattern('d MMMM yyyy HH:mm');
// See: https://unicode-org.github.io/icu/userguide/format_parse/datetime/#datetime-format-syntax for pattern syntax
echo $fmt->format(new \DateTime());
// Output: 6 gennaio 2016 12:10
Use setlocale and strftime together:
setlocale(LC_TIME, array('da_DA.UTF-8','da_DA#euro','da_DA','danish'));
echo strftime("%A"); // outputs 'tirsdag'
Works on my php installation on Windows.
strftime(): Warning! This function has been DEPRECATED as of PHP 8.1.0. Relying on this function is highly discouraged.
Use
http://php.net/manual/en/function.strftime.php
<?php
setlocale(LC_ALL, 'da_DA');
echo strftime("%A %e %B %Y");
?>
I don't think the date() function is quite evolved enough for you, here.
Instead, I would recommend you take a look at the IntlDateFormatter1 class (quoting) :
Date Formatter is a concrete class that enables locale-dependent
formatting/parsing of dates using pattern strings and/or canned
patterns.
There are a couple of examples on the manual page of IntlDateFormatter::format(), where that method is used to display a date in two different languages, by just setting the desired locale.
1. bundled with PHP >= 5.3
This Will Surely works for you if you want norwegian date and month format
$date = '2016-11-16 05:35:14';
setlocale(LC_TIME, array('nb_NO.UTF-8','nb_NO#norw','nb_NO','norwegian'));
echo strftime("%e %b %Y",strtotime($date));
if you want to get other language locale ids like nb_NO then refer this site
International Components for Unicode (ICU) Data
If you are trying to convert a datetime try this:
$fecha = $dateConsulta->format('d-M-Y');
$fecha = str_replace('Jan','Ene',$fecha);
$fecha = str_replace('Apr','Abr',$fecha);
$fecha = str_replace('Aug','Ago',$fecha);
$fecha = str_replace('Dec','Dic',$fecha);

How to format dates based on locale?

In a template I display the day and month of a specific date :
<div class="jour"><?php echo date('d',strtotime($content->getCreatedAt())) ?></div>
<div class="mois"><?php echo date('M',strtotime($content->getCreatedAt())) ?></div>
This works fine, problem is the month name is in English. Where do I specify that I want the month names in another locale, French for instance ?
Symfony has a format_date helper among the Date helpers that is i18n-aware. The formats are unfortunately badly documented, see this link for a hint on them.
default_culture only applies for the symfony internationalisation framework, not for native PHP functions. If you want to change this setting project wide, I would do so in config/ProjectConfiguration.class.php, using setlocale, and then use strftime rather than date:
// config/ProjectConfigration.class.php
setlocale(LC_TIME, 'fr_FR');
// *Success.php
<div class="jour"><?php echo strftime('%d',strtotime($content->getCreatedAt())) ?></div>
<div class="mois"><?php echo strftime('%b',strtotime($content->getCreatedAt())) ?></div>
Note that this requires locale settings to be enabled on your machine. To check, do var_dump(setlocale(LC_ALL, 'fr_FR')); If the result is false, you cannot use setlocale to do this and probably need to write the translation code yourself. Furthermore, you will need to have the correct locale installed on your system. To check what locales are installed, do locale -a at the command line.
Sorry for butting in so late in the day, but I would like to add my own thoughts here. The best international date format that I have come up with is "%e %b %Y", e.g. 9 Mar 2012. I find this much more readable than the ISO format "%Y-%m-%d", e.g. 2012-03-09. According to the docs, the %x format should be locale sensitive, but it does not work for me, at least not on the iPhone. This may be because Safari is not passing the locale in the HTML headers, I do not know.
It is sometimes useful to use an array with different possible values to setlocale().
Especially to support different environments (windows, linux, ...)
setlocale(LC_TIME, array('fr', 'fr_FR', 'fr_FR.utf8', 'french', 'french_FRANCE', 'french_FRANCE.utf8'));
echo strftime("%A %d %B", strtotime(date("Y-m-d")));
As the documentation states:
If locale is an array or followed by additional parameters then each array element or parameter is tried to be set as new locale until success. This is useful if a locale is known under different names on different systems or for providing a fallback for a possibly not available locale.

Categories