Might be a kinda noob question.
But I currently have this code:
<?php
$seconds = 1;
$h = (int)($seconds / 3600);
$m = (int)(($seconds - $h*3600) / 60);
$s = (int)($seconds - $h*3600 - $m*60);
if ($h > 1)
echo "$h hours ago";
else if ($m > 1)
echo "$m minutes ago";
else if ($s > 20)
echo "$s seconds ago";
else echo "a moment ago";
$ThisTime = result
?>
Reminder: seconds is a variable that normally gets defined by an other variable.
What I want is:
for instance with "seconds = 1", the output is: "a moment ago". But i want that echo to be
$ThisTime, how can i do this.
Reminder 2: If the input is 400000, the output is: 111 hours ago. So it defines by multiple variables.
Stupid me:
<?php
$seconds = 1;
$h = (int)($seconds / 3600);
$m = (int)(($seconds - $h*3600) / 60);
$s = (int)($seconds - $h*3600 - $m*60);
if ($h > 1)
$Thistime = "$h hours ago";
else if ($m > 1)
$Thistime = "$m minutes ago";
else if ($s > 20)
$Thistime = "$s seconds ago";
else $Thistime = "a moment ago";
?>
EDIT :::::
Ok, i found another problem.
The time is specified in a database.
And it displays there like this: "1407922779"
How can I cahnge this value to be x minutes ago?
Because if i enter that, it says like 30 years ago (something like that).
While it just has been made.
<?php
$seconds = 1;
$h = (int)($seconds / 3600);
$m = (int)(($seconds - $h*3600) / 60);
$s = (int)($seconds - $h*3600 - $m*60);
if ($h > 1) {
$result = "$h hours ago";
} elseif ($m > 1) {
$result = "$m minutes ago";
} elseif ($s > 20) {
$result = "$s seconds ago";
} else {
$result = "a moment ago";
}
$ThisTime = $result;
?>
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;
}
This question already has answers here:
How to get time difference in minutes in PHP
(21 answers)
Closed 9 years ago.
I have a simple function below that gets seconds and returns it like "2 minutes ago", "9 hours ago" etc...
if I pass 1 on 'relativedate()' function it will just return 1 sec and so on. As we all know 60*60*24*7*30 or 18144000sec = 1 month. Therefore if I pass a value of 18144000 on the parameter, it should return 1 month.However, if I pass a value on the parameter lets say 231440000 on relativedate() which should be more than a year, it is returning '13 months' instead of 1 year.
function relativedate($secs) {
$second = 1;
$minute = 60;
$hour = 60*60;
$day = 60*60*24;
$week = 60*60*24*7;
$month = 60*60*24*7*30;
$year = 60*60*24*7*30*365;
if ($secs <= 0) { $output = "now";
}elseif ($secs > $second && $secs < $minute) { $output = round($secs/$second)." second";
}elseif ($secs >= $minute && $secs < $hour) { $output = round($secs/$minute)." minute";
}elseif ($secs >= $hour && $secs < $day) { $output = round($secs/$hour)." hour";
}elseif ($secs >= $day && $secs < $week) { $output = round($secs/$day)." day";
}elseif ($secs >= $week && $secs < $month) { $output = round($secs/$week)." week";
}elseif ($secs >= $month && $secs < $year) { $output = round($secs/$month)." month";
}elseif ($secs >= $year && $secs < $year*10) { $output = round($secs/$year)." year";
}else{ $output = " more than a decade ago"; }
if ($output <> "now"){
$output = (substr($output,0,2)<>"1 ") ? $output."s" : $output;
}
return $output;
}
echo relativedate(60); // 1 minute
Your year calculation is for 365 Months, not 12 months
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 :(
I've created a function to return the difference between two dates
<?php
class days {
function dateDiff($start, $end) {
$start_ts = strtotime($start);
$end_ts = strtotime($end);
$diff = $end_ts - $start_ts;
$diff1 = ceil($diff / 86400);
return $diff1;
}
}
I have this code in the view :
<?php
$a = new days();
$days = $a->dateDiff($v[17], date('Y/m/d'));
if ($days < 30) {
$ds = $days;
$tm = 'days';
} else {
if ($days < 365) {
$ds = $days / 30;
$tm = 'months';
} else {
$ds = $days / 365;
$tm = 'years';
}
}
$v[17] is the date returned from the database to the view.
When I enter for instance an article in august 2011... It will display :
2.9666666666667 months ago
I ask myself ... How this Ceil method could not return an int value as it's supposed to do?
if that's normal, then what's the solution?
Thank you in advance :)
The ceil funciton works just fine when it returns the number of days.
But the problem is here:
if ($days<365){
$ds=$days/30;
$tm='months';
}
You didn't use ceil this time! You should try something like $ds = ceil($days / 30);.
Same thing for the number of years.
It would probably be more precise to use round instead of ceil, so that 32 days don't translate in 2 months:
$days = $a->dateDiff('10 oct 2011',date('Y/m/d'));
if ($days < 30) {
$ds = $days;
$tm = 'day';
}
else {
if ($days < 365){
$ds = round($days / 30);
$tm = 'month';
}
else {
$ds = round($days / 365);
$tm = 'year';
}
}
if ($ds > 1) {
$tm .= 's';
}
echo "$ds $tm"; # => 1 month; or 2 months using ceil function