Hi there.
We are using the code below to show the amount of years, months, days, weeks, hours and minutes since a date.

We only want the relevant one to show, so if the start date was only a few minutes ago - it should only show minutes, not the others if they're 0.

The following code gives no errors, it simply doesn't echo anything.

Any help appreciated!

$original = strtotime($user['joined']);

function time_since($original) {
  $chunks = array(
    array(60 * 60 * 24 * 365 , 'year'),
    array(60 * 60 * 24 * 30 , 'month'),
    array(60 * 60 * 24 * 7, 'week'),
    array(60 * 60 * 24 , 'day'),
    array(60 * 60 , 'hour'),
    array(60 , 'minute'),
  );

  $today = time(); /* Current unix time  */
  $since = $today - $original;

  if($since > 604800) {
    $print = date("M jS", $original);

if($since > 31536000) {
  $print .= ", " . date("Y", $original);
}
  }

  for ($i = 0, $j = count($chunks); $i < $j; $i++) { 
    $seconds = $chunks[$i][0];
    $name = $chunks[$i][1];

if (($count = floor($since / $seconds)) != 0) {
  // DEBUG print "<!-- It's $name -->\n";
  break;
}
  }

  $print = ($count == 1) ? '1 '.$name : "$count {$name}s";
}


To echo it:

            <li><span><strong><?php echo $print; ?></strong> ago</span></li>

    I don't see the function being called anywhere.

    Also, unless $print is global it cant be seen from outside the function since the function doesn't return it.

      Hey, thanks for your reply.
      I see what you mean, yes.

      I don't actually think this function is going to work for us anyway, it would be ideal if we could reuse it - with this it looks like I'll need this big chunk of code for every time I want to work out time since a certain time.

      Are you aware of any others?
      Thanks!

        Here's one more for the mix (will also work for future times, as well as for any two given times):

        function elapsed($start_ts, $now_ts = null, $min_period = 'minutes') 
        { 
            $periods = array('years', 'months', 'days', 'hours', 'minutes', 'seconds'); 
            if (empty($now_ts)) { 
                $now_ts = time(); 
            } 
            $same = false; 
            if ($now_ts == $start_ts) { 
                $same = true; 
            } elseif ($now_ts < $start_ts) { 
                $tmp_ts = $now_ts; 
                $now_ts = $start_ts; 
                $start_ts = $tmp_ts; 
            } 
            $min_key = array_keys($periods, $min_period);
            $ret['string'] = ''; 
            foreach ($periods as $key => $period) { 
                $ret[$period] = 0; 
                if ($same) { 
                    continue; 
                } 
                while (($start_ts = strtotime('+1 ' . $period, $start_ts)) < $now_ts) { 
                    $ret[$period]++; 
                } 
                $start_ts = strtotime('-1 ' . $period, $start_ts); 
                if ($key > $min_key[0]) { 
                    continue; 
                } 
                if ($ret[$period] !== 0) { 
                    $ret['string'] .= $ret[$period] . ' ' . $period; 
                    if ($ret[$period] === 1) { 
                        $ret['string'] = substr($ret['string'], 0, strlen($ret['string']) - 1); 
                    } 
                    $ret['string'] .= ', '; 
                } 
            } 
            $ret['string'] = rtrim($ret['string'], ', '); 
            return $ret; 
        }
        
        $elapsed_time = elapsed(strtotime('1999-04-04 03:51:11'));
        echo 'Elapsed time: ' . $elapsed_time['string'];
        echo '<pre>';
        print_r($elapsed_time);
        echo '<pre>';
        
        /**
        Elapsed time: 8 years, 2 days, 14 hours, 26 minutes
        Array
        (
            [string] => 8 years, 2 days, 14 hours, 26 minutes
            [years] => 8
            [months] => 0
            [days] => 2
            [hours] => 14
            [minutes] => 26
            [seconds] => 46
        )
        **/

          Ah great, thanks.

          Is the start time always the $elapsed_time?

          Thanks!

            I'm not sure what you mean. The "$elapsed_time" (in the test code) is the array returned by the function. The start time is the first argument passed to the function. If it's the only argument, then the return is the time between it and "now". If two or three arguments are passed, then the return is the time between the two timestamps, unless the second is "null" (then "now" is used)...

            //Between a past time and now:
            $elapsed_time = elapsed(strtotime('2004-05-19'));
            $elapsed_time = elapsed(strtotime('2004-05-19 13:12:11'));
            
            // Between two times:
            $elapsed_time = elapsed(strtotime('2004-05-19'), strtotime('2008-11-20'));
            
            // Between a future time and now:
            $elapsed_time = elapsed(strtotime('2008-11-20'));
            
            // Between a past time and now, with seconds included in the return 'string 'element:
            $elapsed_time = elapsed(strtotime('2004-05-19'), null, 'seconds');
            // With days minumum (not hours, minutes, or seconds) in the 'string':
            $elapsed_time = elapsed(strtotime('2004-05-19'), null, 'days');
            
            // etc.

            The timestamp arguments, of course, don't have to be "strtotime()" expressions. They can be straight Unix timestamps or any expressions that produce timestamps.

              Love it, thank you!

              Problem I'm getting is trying to make it just echo up to the days (not mins, secs etc)

              Using:

               $elapsed_time = elapsed(strtotime($user['joined'], null, 'days'));

              and I get: Warning: Wrong parameter count for strtotime()

              Without, as a normal elapsed_time is fine

              Any ideas? 🙂

              Also, I'd like to ask if there's way for it just to do days (not years, months, weeks, and not minutes, seconds)? We have a small column that can only handle days, and if so, we could use the elapsed function here too.

                Because of a misplaced parenthesis, you are passing two of the arguments for elapsed() to strtotime() instead. The message says it--too many parameters. Put the closing parenthesis for strtotime() where it belongs:

                $elapsed_time = elapsed(strtotime($user['joined']), null, 'days');

                As for the number of days from a certain time to now:

                function days_elapsed($since_ts)
                {
                    return unixtojd() - unixtojd($since_ts);
                }
                
                echo days_elapsed(strtotime('2004-10-09'));

                Edit: I see now that I'm the one who misplaced the parentheses in two of the examples in my previous post. Sorry. I've corrected them.

                  Installer wrote:

                  Edit: I see now that I'm the one who misplaced the parentheses in two of the examples in my previous post. Sorry. I've corrected them.

                  Since there's no way to have this forum do test-runs of posted code, it is vital for whoever is wanting to use code posted here to examine it and try and work out what it's doing; this includes checking out the definitions of any unfamiliar functions to make sure the calls to them have been written properly (I've managed to get arguments back to front on occasion). It also serves as a check that the person posting the code has actually understood the problem (if they didn't, examining their code would reveal that).

                    5 months later

                    Hi guys

                    Sorry to reopen an old thread, but I have a little query regarding this code as above

                    If the time frame given, i.e. null, seconds is used, and something happened in that exact second, it doesn't echo anything out - it just remains blank. For example, I use it along before the word "ago" to assuming it's over a second, I would see "1 second ago", but if it happened now, I just see " ago"

                    Is there anyway for it to say "0 seconds ago" for something happening right now, or even something like "Now" instead of being blank?

                    Hope this makes sense

                      Write a Reply...