I am trying to produce a multilingual using Drupal 6. My site is hosted on a Windows IIS 7.5 Server.
I have gotten my .po files uploaded and everything works great. Im now at the stage where I am going through the site piece by piece to try and weed out anything that escaped my notice when I first translated teh site.
The problem I am having is in trying to display dates in locale formats.
Here is the php code I use to display a local date:
$format = "%A, %b %#d, %Y : %H:%M%p"
if($language->language == 'zh-hans')
{
$loc=setlocale(LC_TIME, 'chs');
}else{
$loc=setlocale(LC_TIME, 'de');
}
$mytime = strftime($format, $time);
$mytime = iconv(mb_detect_encoding($mytime), 'utf-8', $mytime);
echo $mytime;
The above code should display the date in the local format of the current language (chinese of german)
The german displays as expected:
Freitag, Jun 21, 2013 : 16:48
but the chinese output looks like this:
???, ?? 21, 2013 : 16:48??
Any ideas on how to fix this?
The first problem is that setting the LC_TIME category is not enough by itself. The strftime function will attempt to format the time in the appropriate language, but it seems to use the 1252 codepage by default, so it will be incapable of producing the necessary characters for something like Chinese.
I would have expected that setting LC_TIME and maybe LC_CTYPE would be enough, but the only way I could get it to work was with LC_ALL. So your setlocale calls should look like this:
if($language->language == 'zh-hans')
{
$loc=setlocale(LC_ALL, 'chs');
}else{
$loc=setlocale(LC_ALL, 'de');
}
The next problem is that mb_detect_encoding won't always detect the correct encoding. What works for me on Windows is to use setlocale(LC_CTYPE, 0) to get back the current code page.
$codepage = explode('.',setlocale(LC_CTYPE, 0));
$codepage = 'cp'.$codepage[1];
The value returned from the call to setlocale(LC_CTYPE, 0) is a combination of the language name and the codepage number separated by a dot. We split the two parts with explode and then prefix the number with cp to get the code page in a form that iconv can understand.
We can then simply convert the string to utf-8 like this:
$mytime = iconv($codepage, 'utf-8', $mytime);
Related
When using the PHP to return the timezone abbreviation with either date('T') or strftime('%Z') the result does not translate to the localized version of these abbreviations.
In french I have been told the following at the correct translations:
EDT == HAE
EST == HNE
I have tried the following code example:
<?php
setlocale(LC_ALL, 'fr_FR');
echo strftime('%Z');
echo date('T');
?>
All attempts produce EST/EDT rather than the translated versions.
I get the same on Mac and Linux.
I inspected the Gettext MO file for French, like this:
/usr/local/bin/msgunfmt /usr/share/locale/fr/LC_MESSAGES/texinfo.mo
This shows all the translations for things like months and days.
So you should get translations if you do:
echo strftime("%A %e %B %Y\n");
// gives "Vendredi 27 juin 2014"
But the translation file does not appear to contain translations for EST, or EDT - or in fact any others I looked for.
So I guess the answer is that these strings are simply not translated in the standard locale packages.
I feel stupid asking - but I've had a problem with my time format. Using php and pulling date/time from a MySQL db I am trying to format a time display so there are no leading zero characters in my 12 hour format. A space is fine.. Sounds easy right. Probably is...
Style I want is : 6:00 PM NOT 06:00 PM
$result[0][0] is the value of "2013-06-06 18:00:00"
PHP code is now:
echo strftime('%I:%M %p', strtotime($result[0][0]));
//upper case "i" WORKS but has leading zero
PHP code I think I need is :
echo strftime('%l:%M %p', strtotime($result[0][0]));
//Lower case "L" Provides no output
Latter is because according to php manual:
using %l (lower-case 'L') yeilds Hour in 12-hour format, with a space preceding single digits 1 through 12
But when I use this format I get nothing!
What SIMPLE thing am I doing wrong?
(Hmmm , funny how the codes above look exactly alike in the StackOverflow screen but I am typing Upper case i and lower case L... in fact here is upper i --> "I", and here is lower L -->"l" ??) They look identical in this font??
DateTime doing the trick:
<?php
header('Content-Type: text/plain');
$date = DateTime::createFromFormat('Y-m-d H:i:s', '2013-06-06 18:00:00');
echo $date->format('g:i A');
?>
Also, date() doing it:
<?php
header('Content-Type: text/plain');
echo date('g:i A', strtotime('2013-06-06 18:00:00'));
?>
Both show:
6:00 PM
strftime() looks buggy though. %l shows empty string. I tried to put setlocale(LC_TIME, "de_DE"); at the top, but it does not help.
Following might be a reason (from docs):
Not all conversion specifiers may be supported by your C library, in
which case they will not be supported by PHP's strftime().
Additionally, not all platforms support negative timestamps, so your
date range may be limited to no earlier than the Unix epoch. This
means that %e, %T, %R and, %D (and possibly others) - as well as dates
prior to Jan 1, 1970 - will not work on Windows, some Linux
distributions, and a few other operating systems. For Windows systems,
a complete overview of supported conversion specifiers can be found at
» MSDN.
On MSDN there is no %l format code. It might be a reason, that killing return value. In this case strftime() is platform-dependent.
Based on your code, I would also try this to remove the leading zero:
The "g" in PHP, will display the hour without a leading zero.
Time: <?= echo strftime("g:i:sa", strtotime($result['time'])); ?>
A PHP datetime object can be formatted without leading zeroes as
$DateTime->format('j');
Hey you can use the function below to strip out any leading zeros from strftime
function strip_zeros_from_date( $marked_string="") {
//remove the marked zero's
$no_zeros = str_replace('*0', '', $marked_string);
//Remove Reaming
$cleaned_string = str_replace('*', '', $no_zeros);
return $cleaned_string;
}
I am using Spreadsheet_Excel_Reader to read .xls files in PHP.
Everything goes fine until it comes to reading a date. If I am reading a date field, it will always return the date as Nov 30, 1999 (or variations of this date depending upon the format). I have tried setting the OutputEncoding and it's giving the same result. I tried dumping the 'example.xls' that comes with the library and that also produces the same result.
Any help on a workaround for this would be highly appreciated.
You don't need to format your date in excel...if you have a date format in mind wrap it with double quote. e.g "13/04/1987" format("DD/MM/YYYY");
Spreadsheet_Excel_Reader will read this as a normal string with the double quote wrapper around it.
Then in your PHP make a query to remove and replace double quote with nothing.
$var = "13/04/1987";
$removeQuote = str_replace('"','',$var);
After this you will have to replace every occurence of the forwardslash (/) with hypen(-).
$removeSlashes = str_replace('/','-',$removeQuote);
Then use the date function in PHP to format it to your suitability.
$format = date('Y-m-d', strtotime($removeSlashes));
echo $format;
And you'r done... full code goes below.
$var = "13/04/1987";
echo date('Y-m-d',strtotime(str_replace('/','-',str_replace('"','',$var))));
I've run locale -a on my server and can see that it's got Arabic locale settings installed:
ar_AE
ar_AE.iso88596
ar_AE.utf8
However, if I set the locale via:
$locale = array('ar_AE', 'ar_AE.iso88596', 'ar_AE.utf8', 'ar');
setlocale(LC_TIME, $locale);
and output it:
strftime('%A %d %B', $current_date)
The displayed date is in English, not Arabic.
Arabic is the only language this isn't working for: the site I'm working on is in 15 languages and all the others display a translated date.
What's going wrong?
This worked for me with no problems at all.
setlocale(LC_ALL, 'ar_AE.utf8');
If this does not work, then there is another code in your PHP file that interferes with the language.
I'm pulling some dates from a DB and using PHP strftime to format them.
Now, everything works as intended, apart that if I use the %A format, which is supposed to give me the full weekday name the function just returns NULL, unless the date happens to be on a weekend, in which case it correctly returns "Saturday" or "Sunday".
All the other formats work, even %a (short weekday name).
It does not seem to depend on the locale I use, nor on the specific format of the date (same problem happens if I just use strftime on mktime.
My only thought is that it's some sort of incredibly weird configuration problem server side, but I'd like to hear if anyone had other ideas about it...
EDIT: some code, although it's pretty much what I have written before...
$id = (int)$_GET['event'];
$res = mysql_query("SELECT date FROM events WHERE event_id=".$id);
$row = mysql_fetch_array($res);
echo strftime("%a %H:%M", $row['date']);
echo strftime("%A %H:%M", $row['date']);
The first echo works fine, returning for instance Thu 15:30, the second returns NULL unless $row['date'] falls on a Saturday or Sunday.
If this may be of any help the code is inside a class, but I can't see how this may affect the result...
EDIT2: This is NOT a problem with the DB or the date format, otherwise the first echo wouldn't work. Also, I can just remove the DB code, and generate the date with mktime or with strtotime and it still doesn't work.
EDIT3 (solution): Found the issue. In Italian, the names of the days end in ì (e.g. lunedì), apart from Saturday and Sunday, which do not have accented letters. The result of the operation was passed to json_encode which apparently doesn't like accented characters... A call to utf8_encode (or to htmlentities) solved the issue.
According to the manual : http://php.net/manual/en/function.strftime.php
If you're passing something other than a timestamp you're doing it wrong. Can't really say why the first one passes and the second one doesn't. Maybe PHP is trying to compensate. In any case, if you have a text time representation, you need to call strtotime() on it first.
EDIT
I ran the following code in my system
$row['date'] = '2011-04-06 08:33:29';
echo strftime("%a %H:%M", $row['date']);
echo '<br>';
echo strftime("%A %H:%M", $row['date']);
And I got this as the output
Notice: A non well formed numeric value encountered in F:\webroot\utils\test.php on line 4
Thu 00:33
Notice: A non well formed numeric value encountered in F:\webroot\utils\test.php on line 6
Thursday 00:33
You should have notices enabled on your system. Changing it to timestamp should solve it.
EDIT 2
...Also, I can just remove the DB code,
and generate the date with mktime or
with strtotime and it still doesn't
work
If you could post the sample that doesn't work we could have a look
In your comments you say that your database contains dates such as 2011-04-06 08:33:29. But the second argument to strftime should be a unix timestamp such as 1302766547, that is the number of seconds since 1970-01-01 00:00:00 GMT. Try this instead:
echo strftime('%a %H:%M', strtotime($row['date']));