Time Manipulation with Math

For some reason my simple function is failing pretty hard, I just need a bump in the right direction, the current timestamp I use as an example has the time in the top at the comment, says now its about 12 hours ago. Was just wondering if someone could take the time to look at it for me. Thanks.

<?php

// Change Time Format Scripts

// Example Timestamp
// 1286237365 - 8:09 PM Monday October 04, 2010

/* #################### Function Purpose ############### *//*
The purpose of this function is to display time in a more user friendly manner, like
the popular social networking website facebook.
The idea is to compare the timestamp to the current time the end-user is viewing the time,
and display a different format based on that.

For example:
User looks at example timestamp 15 minutes after.
    Displays: 15 minutes ago.
or
User looks at example timestamp an hour after.
    Displays: About an hour ago.
or
User looks at example timestamp 3 days after.
    Displays: Monday at 8:09PM
or
User looks at example timestamp 9 days after.
    Displays: October 4 at 8:09PM. **/


function displayTimePhrase($timestamp)
    {
        $currentTime = mktime();
        
        if ($currentTime-$timestamp < 0) 
            { 
                return "Future Date."; 
            } 
            
        $difference = $currentTime-$timestamp;
        
        $minutes = $difference/60;

        switch ($difference)
            {                
                case $minutes < 60:
                    return "About " . round($minutes) . " minutes ago.";
                break;
                
                case $minutes > 60 && $minutes < 60*24: // greater than an hour, less than a day
                    return "About " . date("g", $minutes) . " hours ago.";
                break;
                
                case $minutes > 60*24 && $minutes < 60*24*7: // greater than a day, less than a week
                    return "" . date("l", $minutes) . " at " . date("g:iA", $minutes) . "";
                break;
                
                case $minutes > 60*24*7 && $minutes < 60*24*7*52: // greater than a week, less than a year
                    return date("F j", $minutes) . " at " . date("g:iA", $minutes);
                break;
                
                case $minutes > 60*24*7*52:
                    return "Over a year ago.";
                break;                
                    
            }
    }
    
    echo displayTimePhrase("1286237365");
    
?>    
        

Much thanks to both of you. Thanks Scallio for complimenting the idea, though it’s pretty much stolen from facebooks use. However I do wonder why the use of switch is wrong? I looked it up first to check if it was right and it directly compared it to a series of if elseif statements. Just curious, thanks.


function displayTimePhrase($timestamp){ 
	$difference = time() -$timestamp; 
		
	if ($difference < 0 ){
		#$timestamp in the future
		return "Future date";
			
	}elseif ($difference < 3600 ){
		# within the hour
		if(($difference / 60 ) > 1){
			$aesthetic = ($difference < 120) ? '' : 's';
			return "About " . floor($difference / 60) . " minute$aesthetic ago";
		}else{
			return "About " . $difference . " seconds ago";
		}
	
	}elseif(3600< $difference && $difference <86400){
		#more than an hour but same day
		$aesthetic = (floor($difference/3600) == 1) ? '' : 's';
		return "About ". floor($difference/3600) . " hour$aesthetic ago";
	
	}elseif(86400 < $difference && $difference  < 604800){
		# within the week but not today
		return date("l", $timestamp)." at ".date("g:iA", $timestamp);

	}elseif(604800 < $difference && $difference  < 31449600){
		#not this week, but this year
		return date("F j", $timestamp)." at ".date("g:iA", $timestamp);

	}elseif(31449600 < $difference && $difference ){
		#over a year ago
		return "Over a year ago";
	}
}

echo displayTimePhrase(strtotime("2010-10-07 12:00"));

Enjoy.

It is indeed used to replace a series of else statements, but in a set manner.
That is, in each case you can only check for a value, not for an expression.

Take a look at the page on switch in the PHP manual: http://nl3.php.net/manual/en/control-structures.switch.php

You’ll notice that they only use it against constants, e.g.

case 0:
case ‘apple’:
case ‘banana’:

etc

As a further example, consider the following:


switch ($somevar)
{
   case 1:
     echo 'Somevar is 1';
     break;
}

This reads as if ($somevar == 1)

So with your example:


switch ($difference)
{                
   case $minutes < 60:
      return "About " . round($minutes) . " minutes ago.";
      break;
}

That would read as if ($difference == $minutes<60), so if minutes is smaller than 60 it’ll check if $difference is false, otherwise it’ll check if difference is true.

Does that make sense?

PS. There is no example of this in the manual, but you can also test it against another variable


switch ($somevar)
{
   case $someothervar:
     echo '$somevar = '.$someothervar;
     break;
}

The date function expects the second parameter to be a timestamp. The $minutes variable you have is not a timestamp, just the number of minutes between then an now.
So for example for the hours you would use round($minutes/60), for the day you would use date(‘l’, $timestamp) and also use $timestamp instead of $minutes for the last case.

Also, the way you’re using the switch statement is incorrect.
I would change it back to only if statements


if ($minutes < 60)
  return ...
if ($minutes < 60*24)
  return ...
...
return date('d-m-Y', $timestamp);

Note that because of the use of return you don’t need to use else here; either the if evaluates to true and the function stops because a value is returned, or the if doesn’t evaluate to true and the function will go on to the next if statement.

Nice idea by the way, simple and elegant :slight_smile: