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;
}
Related
I got PHP 7.0.8 (FPM) running on FreeBSD 10.1 and nginx. I need to display time in preferred format by the country where user resides.
setlocale(LC_ALL, "ru_RU.UTF-8");
date_default_timezone_set("Europe/Moscow");
echo strftime('%X', time());
// Returns 21:23:12 (correct) because 24-hr format is preferred in Russia.
setlocale(LC_ALL, "en_US.UTF-8");
date_default_timezone_set("America/New_York");
echo strftime('%X', time());
// Returns 21:23:12 (incorrect) must return 9:23:12 pm as preferred format in U.S.
This looks like an issue with my server or PHP version, because
other users are getting correct results.
locale -a return contains both ru_RU.UTF-8 and en_US.UTF-8.
echo setlocale(LC_ALL, "en_US.UTF-8") returns correct locale.
No special configuration is applied.
Please help me to resolve this. Thanks.
%X Preferred time representation based on locale, without the date
P.S. Preferred date %x works correctly displaying dd.mm.yyyy for Russia and mm/dd/yyyy for U.S.
Same on FreeBSD 10.3:
php -r 'date_default_timezone_set("Europe/Paris"); var_dump(setlocale(LC_ALL, "en_US.UTF-8"), strftime("%X", time()));'
string(11) "en_US.UTF-8"
string(8) "15:03:07"
First, ls -l /usr/share/locale/en_US.UTF-8/LC_TIME returns:
/usr/share/locale/en_US.UTF-8/LC_TIME# -> ../en_US.ISO8859-1/LC_TIME
So en_US.UTF-8 is, in fact, a symlink to en_US.ISO8859-1.
Then, If we look into /usr/src/share/timedef/en_US.ISO8859-1.src (you need sources installed), we find:
#
# X_fmt
#
%H:%M:%S
Which explains the actual result when you would expect %I:%M:%S %p (or %r).
Possible solutions:
fill a bug report if you think it is relevant and/or1 patch the file above then rebuild world (I guess)
handle this specific case:
echo strftime(0 === strpos(setlocale(LC_ALL, '0'), 'en_US') ? '%r' : '%X');
prefer using IntlDateFormatter which does not rely on system-locales (assumed by ICU library). Eg:
$timefmt = new IntlDateFormatter('en_US', IntlDateFormatter::NONE, IntlDateFormatter::MEDIUM);
$timefmt->format(date_create());
1 it seems that X_fmt is valued to %I:%M:%S %p in trunk and 11-STABLE
Update:
the commit altering X_fmt was reverted since (ie on FreeBSD >= 11, X_fmt is still defined as %H:%M:%S)
on FreeBSD 11, the file defining time formats is /usr/src/share/timedef/en_US.UTF-8.src (the symbolic link to en_US.ISO8859-1 locale is gone)
Excerpt from /usr/share/i18n/locales/en_US on ubuntu 12.04:
% Appropriate time representation (%X)
% "%r"
t_fmt "<U0025><U0072>"
%
% Appropriate AM/PM time representation (%r)
% "%I:%M:%S %p"
t_fmt_ampm "<U0025><U0049><U003A><U0025><U004D><U003A><U0025><U0053><U0020>/
<U0025><U0070>"
Please note the %I in AM/PM date for %r.
the %X in unicode is 25 70 which is %P.
And from man date (stripped for simplicity):
%H hour (00..23)
%I hour (01..12)
%p locale's equivalent of either AM or PM; blank if not known
%P like %p, but lower case
%r locale's 12-hour clock time (e.g., 11:11:04 PM)
%R 24-hour hour and minute; same as %H:%M
%x locale's date representation (e.g., 12/31/99)
%X locale's time representation (e.g., 23:13:48)
Reading all this file, it should work as expected so I suspect your setup use a different locale file or fallback to C locale (if the locale file is not there for example)
Now for setlocale, it will return false only in case you give a bad variable (I.e LCAL instead of LCALL) but will return what the system returns for other cases:
Note: The return value of setlocale() depends on the system that PHP
is running. It returns exactly what the system setlocale function
returns.
On "linuxes" setlocale returns NULL which is not always seen as false (see here) which may be a source of your problem, I can't swear as I've no FreeBSD running to confirm this point.
In order to get the date in the right format I want I used date("d-m-Y"). Now I want to get the time in addition to the date in the following format H:M:S How can I procede ?
Anytime you have a question about a particular function in PHP, the easiest way to get quick answers is by visiting php.net, which has great documentation on all of the language's capabilities.
Looking up a function is easy, just visit http://php.net/<function name> and it will forward you to the appropriate place. For the date function, we'll visit http://php.net/date.
We immediately learn a couple things about this function by examining its signature:
string date ( string $format [, int $timestamp = time() ] )
First, it returns a string. That's what the first string in the above code means. Secondly, the first parameter is expected to be a string containing the format. There is an optional second parameter for passing in your own timestamp (to construct strings from some time other than now).
date("d-m-Y") // produces something like 03-12-2012
In this code, d represents the day of the month (with a leading 0 is necessary). m represents the month, again with a leading zero if necessary. And Y represents the full 4-digit year. All of these are documented in the aforementioned link.
To satisfy your request of getting the hours, minutes, and seconds, we need to give a quick look at the documentation to see which characters represents those particular units of time. When we do that, we find the following:
h 12-hour format of an hour with leading zeros 01 through 12
i Minutes with leading zeros 00 to 59
s Seconds, with leading zeros 00 through 59
With this in mind, we can no create a new format string:
date("d-m-Y h:i:s"); // produces something like 03-12-2012 03:29:13
Hope this is helpful, and I hope you find the documentation has benefiting to your development as I have to mine.
You can combine both in the same date function call
date("d-m-Y H:i:s");
You can have both formats as an argument to the function date():
date("d-m-Y H:i:s")
Check the manual for more info : http://php.net/manual/en/function.date.php
As pointed out by #ThomasVdBerge to display minutes you need the 'i' character
$t = DateTime::createFromFormat('Gi', '900');
$time_str = $t->format('gi a');
echo $time_str; //outputs 600 pm instead of 9am. Why? and How do I get 9am?
I am not sure where I am going wrong.. I am following what is given here in terms of date formatting:
http://php.net/manual/en/function.date.php
Thanks!
The documentation you linked is for the date() function. The DateTime::createFromFormat is not the same (though the format strings are pretty much identical).
I expect the format parsing is having trouble recognizing the difference between the hour and minute components.
If you split them up with a space, you get the desired result:
$t = DateTime::createFromFormat('G i', '9 00');
$time_str = $t->format('gi a');
echo $time_str;
// Output is 900 am
Edit:
The inability for PHP to parse a format string like Gi is a known bug. The parser for G doesn't know whether to read 9 or 90 and in the latter case that 90 is too high.
As i said in my comment this works :
$t = DateTime::createFromFormat('G i', '9 00');
$time_str = $t->format('gi a');
echo $time_str.PHP_EOL;
Cannot find any where written down - but suspect the time needs to be separated ... either by space or colon or something else
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']));
Hallo can someone explain the behaviour of strtotime function with year in non-standard format.
echo date("d-m-Y",strtotime('02-12-10')) .'<br>'; //10-12-2002
echo date("d-m-Y",strtotime('09.09.10')) .'<br>'; //02-09-2010 --How this is interpreted?
echo date("d-m-Y",strtotime('02-12-2010')) .'<br>'; //02-02-2010
echo date("d-m-Y",strtotime('09.09.2010')) .'<br>'; //09-09-2010
I wanted to convert strings of format dd.mm.yy(09.09.10) to datetime format.
strtotime() can be a bit flaky in such cases. It is built to recognize standard american date formats.
If you can use PHP > 5.3, consider using DateCreateFromFormat which has the big advantage of accepting a pre-defined format string to parse the incoming data.
On pre-5.3 platforms, strptime() seems to offer a second-best alternative. It's not available on Windows and has some minor issues - be sure to read the manual page before using.
From the manual:
The "Day, month and two digit year, with dots or tabs" format (dd [.\t] mm "." yy) only works for the year values 61 (inclusive) to 99 (inclusive) - outside those years the time format "HH [.:] MM [.:] SS" has precedence.
You are using '09.09.10' and 10 does not fall in the valid range hence change the separator to -
This is not 2-digit year question.
this is non-standard format question.
And asking impossible things from mere a program.
Even me, not being a computer, have no idea what these 09's dooes mean in your date. is it day.month.year? or year.month.day or whatever?
Assuming it's day.month.year:
$list($d,$m,$y) = explode("09.09.10");
echo "$d-$m-20$y";