This question already has answers here:
Convert seconds to Hour:Minute:Second
(30 answers)
Closed 11 months ago.
Is there a built-in php function that converts number of seconds to military time?
So it will take 3600 and output 01:00:00.
Try this:
<?php
$seconds = 3600;
echo sprintf("%02d:%02d:%02d",$seconds/3600,($seconds/60)%60,$seconds%60);
?>
$seconds = 3600;
echo gmdate('H:i:s', $seconds);
xato was nearly there.
With this approach it's a little bit of a cheat but I believe it will behave in exactly the way that you want it to with hours, minutes and seconds.
edit: and the behaviour will be consistent across all servers regardless of their TZ settings
$seconds = 3600;
echo date('H:i:s', $seconds);
There you go. I might have a use for such a function myself sometime, so I wrote that for you.
function time_format($time) {
if($time > 86400) {
return "more than 1 day";
}
$display = '';
if ($time >= 3600) {
$hours = floor($time/3600);
$time = $time%3600;
if($hours <= 9) { $display .= "0"; }
$display .= $hours;
} else {
$display .= "00";
}
$display .= ":";
if($time >= 60) {
$minutes = floor($time/60);
$time = $time%60;
if($minutes <= 9) { $display .= "0"; }
$display .= $minutes;
} else {
$display .= "00";
}
$display .= ":";
if($time > 0) {
$seconds = $time;
if($seconds <= 9) { $display .= "0"; }
$display .= $seconds;
} else {
$display .= "00";
}
return $display;
}
EDIT: seeing bozdoz's answer makes me feel deeply ashamed :(
Related
I have a challenge I am trying to add all the time the user has spent online but I am getting wrong totals. I am taking values from mysql database and I want to get total hours, minutes and seconds for each user. Currently I am getting totals for each session but now I want total for all sessions and display all users in a table where I have username and time spent online and must be able to filter results by date getting total time spent in hours, minutes and seconds for the filtered date. How can I do that. My code is as follows:
$i=0;
foreach ($report as $online)
{
$id = $online['userid'];
$sql = "SELECT start_time, end_time FROM user_sessions where userid=$id AND end_time !='0000-00-00' || end_time != '' LIMIT $start, $per_page";
$timeOnline = $obj->MySQLSelect($sql);
++$i;
$start = $timeOnline[$i]['start_time'];
$end = $timeOnline[$i]['end_time'];
$totalhours = get_saved_time($end, $dstart);
$sum = $totalhours;
?>
<tr class="gradeA">
<?php if (!empty($sum)): ?>
<td><? echo $generalobjAdmin->clearName($online['fname'].' '.$online['lname']); ?></td>
<td align="center"><?= Convert($sum); ?></td>
<?php endif; ?>
</tr>
<? } ?>
public function get_saved_time($end_time,$start_time)
{
$past = $start_time;
$current = strtotime($end_time);
$past = strtotime($past);
return round(abs($current-$past));
}
function Convert($seconds) {
$hours = floor($seconds / 3600);
$mins = floor(($seconds / 60) % 60);
$secs = $seconds % 60;
if (strlen($hours) == 1)
$hours = "0" . $hours;
if (strlen($secs) == 1)
$seconds = "0" . $secs;
if (strlen($mins) == 1)
$minutes = "0" . $mins;
if ($hours == 0){
$mint="";
$secondss="";
if($mins > 01){
$mint = "$mins mins";
}else{
$mint = "$mins min";
}
if($secs > 01){
$secondss = "$secs seconds";
}else{
$secondss = "$secs second";
}
$ret = "$mint $secondss";
} else {
$mint="";
$secondss="";
if($mins > 01){
$mint = "$mins mins";
}else{
$mint = "$mins min";
}
if($secs > 01){
$secondss = "$secs seconds";
}else{
$secondss = "$secs second";
}
if($hours > 01){
$ret = "$hours hrs $mint $secondss";
}else{
$ret = "$hours hr $mint $secondss";
}
}
return $ret;
}
I have for example 259201 seconds in a variable.
How can I transform it in a "normally" time like 4 days 00:00:01 ?
Thank you in advance!
Is very simple to do this in PHP:
<?php
$secs = "259201";
$days = gmdate("d", $secs);
$hoursminssecs = gmdate("H:i:s", $secs);
if ($days == 0) { $days = empty($days); } elseif ($days == "1") { $days = "1 day"; } else { $days = $days." days"; }
echo $days." - ".$hoursminssecs
?>
Hopes it helps you!
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 9 years ago.
I am wondering what is the most elegant way of calculating a human readable elasped time given a certain amount of seconds. I want to write this in PHP.
Here is the output needed:
elapsedTimeInSeconds > one year, output "# years, # months"
elapsedTimeInSeconds > one month, output "# months, # days"
elapsedTimeInSeconds > one day, output "# days, # hours"
elapsedTimeInSeconds > one hour, output "# hours, # minutes"
elapsedTimeInSeconds > one minute, output "# minutes, # seconds"
I have tried different solutions that are awkward and full of conditional statements, but I was hoping for a more recursive and "clean code" method.
I think this is more flexible, as you can easily add new units like decade, century, etc, and the code wouldn't change:
$names = array("seconds", "minutes", "hours", "days", "months", "years");
$values = array(1, 60, 3600, 24 * 3600, 30 * 24 * 3600, 365 * 24 * 3600);
$time = ...elapsedTimeInSeconds...;
for($i = count($values) - 1; $i > 0 && $time < $values[$i]; $i--);
if($i == 0) {
echo intval($time / $values[$i]) . " " . $names[$i];
} else {
$t1 = intval($time / $values[$i]);
$t2 = intval(($time - $t1 * $values[$i]) / $values[$i - 1]);
echo "$t1 " . $names[$i] . ", $t2 " . $names[$i - 1];
}
Thank you for your suggestions.
I mainly used Waygood and ChrisForrence's suggestions for this method. I tried to keep it as simple as possible and introduced simple arguments such as detail level and delimiter (for string ouput).
public function elapsedTimeHumanReadable($date = null, $detailLevel = 2, $delimiter = ' et ')
{
if($date === null)
{
$date = self::now();
}
$sec = $this->elapsedSecond($date);
$a_sec = 1;
$a_min = $a_sec * 60;
$an_hour = $a_min * 60;
$a_day = $an_hour * 24;
$a_month = $a_day * 30;
$a_year = $a_day * 365;
$text = '';
$resultStack = array();
if($sec >= $a_year)
{
$years = floor($sec / $a_year);
$text .= $years . $this->plural($years, ' an');
$sec = $sec - ($years * $a_year);
array_push($resultStack, $text);
}
if($sec >= $a_month)
{
$months = floor($sec / $a_month);
$text = $months . ' mois';
$sec = $sec - ($months * $a_month);
array_push($resultStack, $text);
}
if($sec >= $a_day)
{
$days = floor($sec / $a_day);
$text = $days . $this->plural($days, ' jour');
$sec = $sec - ($days * $a_day);
array_push($resultStack, $text);
}
if($sec >= $an_hour)
{
$hours = floor($sec / $an_hour);
$text = $hours . $this->plural($hours, ' heure');
$sec = $sec - ($hours * $an_hour);
array_push($resultStack, $text);
}
if($sec >= $a_min)
{
$minutes = floor($sec / $a_min);
$text = $minutes . $this->plural($minutes, ' minute');
$sec = $sec - ($minutes * $a_min);
array_push($resultStack, $text);
}
if($sec >= $a_sec)
{
$seconds = floor($sec / $a_sec);
$text = $sec . $this->plural($seconds, ' seconde');
$sec = $sec - ($sec * $a_sec);
array_push($resultStack, $text);
}
$result = $resultStack[0];
for($i = 1; $i <= $detailLevel - 1; $i++)
{
if(!empty($resultStack[$i]))
{
$result .= $delimiter . $resultStack[$i];
}
}
return $result;
}
I also added a very simple plural function to return the time unit in a correct grammatical fashion:
public function plural($value, $unit)
{
if($value > 1)
{
return $unit . 's';
}
else
{
return $unit;
}
}
I am not really happy with the for loop, but it actually works fine.
Anyway, thank you very much for your help!
I use this:
function durationFormat($time)
{
if(gmdate("Y", $time)>1970) return (1970-gmdate("Y",$time)).gmdate(" \y\r\s ", $time).(gmdate("n",$time)-1).gmdate(" \m\o\n\t\h\s ", $time).(gmdate("j",$time)-1).gmdate(" \d\a\y\s H:i:s", $time);
if(gmdate("n", $time)>1) return (gmdate("n",$time)-1).gmdate(" \m\o\n\t\h\s ", $time).(gmdate("j",$time)-1).gmdate(" \d\a\y\s H:i:s", $time);
if(gmdate("j", $time)>1) return (gmdate("j",$time)-1).gmdate(" \d\a\y\s H:i:s", $time);
return gmdate("H:i:s", $time);
}
It's a bit quick and dirty but does the job
OR
function durationFormat2($seconds)
{
$a_sec=1;
$a_min=$a_sec*60;
$an_hour=$a_min*60;
$a_day=$an_hour*24;
$a_week=$a_day*52;
//$a_month=$a_day*(floor(365/12));
$a_month=$a_day*30;
$a_year=$a_day*365;
$params=2;
$text='';
if($seconds>$a_year)
{
$years=floor($seconds/$a_year);
$text.=$years.' years ';
$seconds=$seconds-($years*$a_year);
$params--;
}
if($params==0) return $text;
if($seconds>$a_month)
{
$months=floor($seconds/$a_month);
$text.=$months.' months ';
$seconds=$seconds-($months*$a_month);
$params--;
}
if($params==0) return $text;
if($seconds>$a_week)
{
$weeks=floor($seconds/$a_week);
$text.=$weeks.' weeks ';
$seconds=$seconds-($months*$a_week);
$params--;
}
if($params==0) return $text;
if($seconds>$a_day)
{
$days=floor($seconds/$a_day);
$text.=$days.' days ';
$seconds=$seconds-($days*$a_day);
$params--;
}
if($params==0) return $text;
$H=gmdate("H", $seconds);
if($H>0)
{
$text.=$H.' hours ';
$params--;
}
if($params==0) return $text;
$M=gmdate("i", $seconds);
if($M>0)
{
$text.=$M.' minutes ';
$params--;
}
if($params==0) return $text;
$S=gmdate("s", $seconds);
$text.=$S.' seconds ';
return $text;
}
I want to do what StackOverflow is doing which is saying exactly how long it's been since the last post. There is a catch though, SO displays certain information based on how long the ago the last post was - for example, if the post was less than a day ago, they post how many hours ago the last post was; if the post was less than an hour ago they post how many minutes ago it was, etc.
I'm working with a MYSQL DateTime field in the following format:
2012-09-19 13:28:45
I want to compare the above to the time NOW and so I converted that time using PHP's strtotime function and tried comparing the two dates through a function I put together (below). Granted, this is probably the WORST possible way of doing this but after reading about PHP's Date and DateTime functions I'm starting to become very, very confused.
function get_date_format($strToTimeString){
$minute = 60;
$hour = $minutes * 60;
$day = $hour * 24;
$week = $day * 7;
$month = $week * 4;
$year = $month * 12;
$timeNow = strtotime("now");
$timeDiff = $timeNow - $strToTimeString;
if($timeDiff > $minute){
if($timeDiff > $hour){
if($timeDiff > $day){
if($timeDiff > $week){
if($timeDiff > $month){
if($timeDiff > $year){
// Years ago
}
else{
// Months ago
}
}
else{
// Weeks ago
}
}
else{
// Days ago
}
}
else
{
// Hours ago
}
}
else{
// Minutes ago
}
}
else{
// Seconds ago
}
}
Is there a better way to do this? As I mentioned above, I had no luck when trying to use DateTime->diff
I really appreciate any help.
Use DateTime. Here's sample:
$now = new DateTime('now');
$posted = new DateTime($postDateFromDBHere);
$interval = $posted->diff($now);
var_dump($interval);
echo $interval->format('%y-%m-%d %h:%m:%s'); //You can do similar to format your output as you wish.
Use DateTime and DateTime:diff then check each value:
function returnInterval($date){
$datetime1 = new DateTime($date);
$datetime2 = new DateTime();
$diff = $datetime1->diff($datetime2);
$string = '';
$pass = '';
if($diff->y){
$string .= ($diff->y == 1) ? $diff->y." year" : $diff->y." years";
$pass = ', ';
}
if($diff->m){
$string .= $pass;
$string .= ($diff->m == 1) ? $diff->m." month" : $diff->m." months";
$pass = ', ';
}
if($diff->d){
$string .= $pass;
$string .= ($diff->d == 1) ? $diff->d." day" : $diff->d." days";
$pass = ', ';
}
if($diff->h){
$string .= $pass;
$string .= ($diff->h == 1) ? $diff->h." hour" : $diff->h." hours";
$pass = ', ';
}
if($diff->i){
$string .= $pass;
$string .= ($diff->i == 1) ? $diff->i." minute" : $diff->i." minutes";
$pass = ', ';
}
if($diff->s){
$string .= $pass;
$string .= ($diff->s == 1) ? $diff->s." second" : $diff->s." seconds";
}
$pos = strrpos($string, ',');
$string = substr_replace($string, ' and ', $pos, 2);
return $string;
}
echo returnInterval('2012-09-19 13:28:45');
// 8 days, 13 hours, 47 minutes and 44 seconds
After long searching, I got something close to what rottentomatoes used on their forum:
function realTimeSince($time){
define(MINUTE, 60);
define(HOUR, 60*60);
define(DAY, 60*60*24);
define(MONTH, 60*60*24*30);
$delta = strtotime(gmdate("Y-m-d H:i:s", time())) - strtotime($time);
if ($delta < 1 * MINUTE) {
return $delta == 1 ? "one second ago" : $delta . " seconds ago";
}
if ($delta < 2 * MINUTE) {
return "a minute ago";
}
if ($delta < 45 * MINUTE) {
return floor($delta / MINUTE) . " minutes ago";
}
if ($delta < 90 * MINUTE) {
return "an hour ago";
}
if ($delta < 24 * HOUR) {
return floor($delta / HOUR) . " hours ago";
}
if ($delta < 48 * HOUR) {
return "yesterday";
}
if ($delta < 30 * DAY) {
return floor($delta / DAY) . " days ago";
}
if ($delta < 12 * MONTH) {
$months = floor($delta / DAY / 30);
return $months <= 1 ? "one month ago" : $months . " months ago";
} else {
$years = floor($delta / DAY / 365);
return $years <= 1 ? "one year ago" : $years . " years ago";
}
}
so you can use it like this:
realTimeSince('2012-11-12 00:09:54'); //which can be got from a MySQL TIMESTAMP field
modified a little based on http://www.ferdychristant.com/blog//archive/DOMM-7QEFK4
Try the following function
function time_ago($date)
{
//echo "ss";
if (empty($date)) {
return "No date provided";
}
$periods = array("sec", "min", "hr", "day", "week", "month", "year", "decade");
$lengths = array("60","60","24","7","4.35","12","10");
$now = time();
$unix_date = strtotime($date);
// check validity of date
if (empty($unix_date)) {
return "Bad date";
}
// is it future date or past date
if ($now >= $unix_date) {
$difference= $now - $unix_date;
$tense = "ago";
} else {
$difference = $unix_date - $now;
$tense = "from now";
}
for ($j = 0; $difference >= $lengths[$j] && $j < count($lengths)-1; $j++) {
$difference /= $lengths[$j];
}
$difference = round($difference);
if ($difference != 1 && $j != 0) {
$periods[$j].= "s";
}
if($difference!=0)
return "$difference $periods[$j] {$tense}";
else
return "a few seconds ago";
}
or
function time_elapsed_since ($postedDateTime){
$time = time() - $postedDateTime; // to get the time since that moment
$tokens = array (
31536000 => 'year',
2592000 => 'month',
604800 => 'week',
86400 => 'day',
3600 => 'hour',
60 => 'minute',
1 => 'second'
);
foreach ($tokens as $unit => $text) {
if ($time < $unit) continue;
$numberOfUnits = floor($time / $unit);
return $numberOfUnits.' '.$text.(($numberOfUnits>1)?'s':'');
}
}
time_elapsed_since($postedDateTime).' ago';
I need to convert 1774132 to 30:42 or 30 minutes and 42 seconds or whatever the output of this is. Is there any PHP function that does this?
I found this online a long time ago, but I have no idea where from anymore:
<?php
function secondsToWords($seconds)
{
/*** return value ***/
$ret = "";
/*** get the hours ***/
$hours = intval(intval($seconds) / 3600);
if($hours > 0)
{
$ret .= "$hours hours ";
}
/*** get the minutes ***/
$minutes = bcmod((intval($seconds) / 60),60);
if($hours > 0 || $minutes > 0)
{
$ret .= "$minutes minutes ";
}
/*** get the seconds ***/
$seconds = bcmod(intval($seconds),60);
$ret .= "$seconds seconds";
return $ret;
}
echo secondsToWords(time());
?>
Something like this should work:
printf("%d:%d:%d",$m / (1000*60*60), $m % (1000*60*60) / (1000*60),$m % (1000*60*60) % (1000*60) / 1000 );