Jump to content

Recommended Posts

Hi.. everyone!

 

I've noticed that Facebook, Twitter, and lots of other sites are using a relative date and time string description for user posts and comments. For example, "comment written about 3 months ago" instead of "comment written on September 20, 2012." I decided to do the same thing on my site. In my site I need to display 1 day ago, 2 days ago, 3 days ago,...... 1 week ago, 2 weeks ago, .... 1 months ago, 2 months ago, ...... 1 year ago, 2 years ago... etc. Already I have got user registered date and need to check it with current date and time and need to diplay it with above style on my home page.

 

In my database, user registered date format is like this .. '2012-09-23 09:11:02'

 

can anybody help me to build this script... and it will greatly appriciated.

 

Thank you.

You'll want to find the difference between the current date and the posting date, in seconds. The easiest way to do that is to convert them to a unix timestamp and just subtract the two. You can use the UNIX_TIMESTAMP function in your MySQL query, or PHP's strtotime() to convert a date to a unix timestamp.

 

After that you just convert the # of seconds into your textual string. There are lots of implementations of functions for this if you search google, or you can try writing your own.

thanks for response... I tried with this function. But second and minutes not working there...

 

$postedDateTime = '2012-09-23 09:11:02';
 //$postedDateTime = date('2012-09-23 09:11:02');

 function time_elapsed_since($postedDateTime){   
    $time = time() - strtotime($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':'');
				  }   
 }
 echo 'Mr. Tharanga added his tutor profile ' . time_elapsed_since($postedDateTime) . ' ago';

 

any comments are greatly appreciated.

 

Thank you.

You're returning to early. Inside your foreach loop you want to concatenate each of the parts together to build a string, then return the string at the end of the function. Right now you will only see the largest segment because you return right away after generating it.

 

Im calling it something like this..

 

include('includes/time_elapsed_since.php');

while ( $row = @mysqli_fetch_array ( $r, MYSQLI_ASSOC )) {

// some coding....
echo ' <span>(';
echo time_elapsed_since($addedDate);
 echo ' ago)</span>';

}

Edited by thara

Like @kicken mentioned, don't return early and concatenate the results.

 

$str = '';
foreach ($tokens as $unit => $text) {
 if ($time < $unit) 
   continue;
 $numberOfUnits = floor($time / $unit);
 $str .= $numberOfUnits.' '.$text.(($numberOfUnits>1)?'s':'');
}
return $str;

You need to reduce time by the units "consumed" each time through the loop

 

   foreach ($tokens as $unit => $text) {
	  if ($time < $unit) continue;
	  $numberOfUnits = floor($time / $unit);
	  $res .= sprintf('%d %s ', $numberOfUnits, $text );
	  $time %= $unit*$numberOfUnits;
   }
   return $res;  

Edited by Barand

That is because your function/calculation is wrong. @kicken and I just pointed out to get the X months Y weeks Z days .. you needed to concatenate the results.

 

The correct calculation goes something like:

 

function time_elapsed_since($postedDateTime) {
 $diff = abs(time() - strtotime($postedDateTime)); // to get the time since that moment   

 $years   = (int) $years   =       $diff / 31536000;
 $months  = (int) $months  =      ($diff % 31536000) / 2592000;
 $weeks   = (int) $weeks   =     (($diff % 31536000) % 2592000) / 604800;
 $days    = (int) $days    =    ((($diff % 31536000) % 2592000) % 604800) / 86400;
 $hours   = (int) $hours   =   (((($diff % 31536000) % 2592000) % 604800) % 86400) / 3600;
 $minutes = (int) $minutes =  ((((($diff % 31536000) % 2592000) % 604800) % 86400) % 3600) / 60;
 $seconds = (int) $seconds = (((((($diff % 31536000) % 2592000) % 604800) % 86400) % 3600) % 60);

 return ($years   ? $years   .' years '   : '').
        ($months  ? $months  .' months '  : '').
        ($weeks   ? $weeks   .' weeks '   : '').
        ($days    ? $days    .' days '    : '').
        ($hours   ? $hours   .' hours '   : '').
        ($minutes ? $minutes .' minutes ' : '').
        ($seconds ? $seconds .' seconds ' : '');
}

 

The very verbose format can be shortened.

 

Something like:

 

echo time_elapsed_since('+9876 minutes');

 

Returns:

6 days 20 hours 36 minutes

 

Much easier is it of course to simply:

 

$diff = new DateTime(new DateTime('+9876 minutes'));

 

Which returns a DateInterval and has several properties to get the number of seconds/minutes/hours/..

http://php.net/manual/en/class.dateinterval.php

 

Or use Carbon:

echo (new Carbon)->diffForHumans(new Carbon('+9876 minutes'));

Edited by ignace

ignace: His calculation was almost correct, he just wasn't reducing the elapsed time on each iteration as my code does with

 

$time %= $units * $numberOfUnits;

 

As you can see by my result, it works

thanks for all answers. both coding work for me.. But another problem encountered me when I use my earlier function. I used it for display 1 output. like 1 day ago, 1 week ago, 2 months ago.. .etc.

 

this is my function again...

 

<?php
function time_elapsed_since ($addedDate){
$time = time() - strtotime($addedDate); // 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':'');
			 }
}
?>

 

This function is work for weeks and months. that mean if a profile has added before 3 weeks, the output display correctly as '3 weeks ago' as well as if a profile has added before 2 months, the output display it as '2 months ago' etc. And just now I added a profile to my website to check seconds and minutes work like that . But there, not display '1 second ago, 2 seconds ago, or 1 minute ago, 3 minutes ago.. etc. Its only display string 'ago'.

 

can you tell me what is the mistake for it..

 

any comments would be greatly appreciated.

 

Thank you.

Edited by thara

@barand sorry, my apologies, that was a response to thara, it just was posted with a bad timing apparently IPB does not always report when new content was added and I didn't check due to this handy feature.

Edited by ignace

thara: your function worked for me

Now: 2012-09-26 17:25:40
Posted date/time: 2012-09-26 17:25:02
38 seconds ago

 

and a little later

Now: 2012-09-26 17:29:00
Posted date/time: 2012-09-26 17:25:02
3 minutes ago

Edited by Barand

Barand please check this again..

 

$date = '2012-09-26 17:25:02';
$postedDateTime = strtotime($date);
//$postedDateTime = date('2012-09-23 09:11:02');
//$postedDateTime = strtotime('2012-09-25 09:11:02');

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':'');
			 }
}
echo 'Mr. Tharanga added his tutor profile ' . time_elapsed_since($postedDateTime) . ' ago';

?>

 

my output is "Mr. Tharanga added his tutor profile ago"

 

NOTE: im trying on local host using wamp server..

Edited by thara

Your latest function:

 

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':'');
 }
}
echo 'Mr. Tharanga added his tutor profile ' . time_elapsed_since('+38 minutes') . ' ago';

 

Returns

 

Mr. Tharanga added his tutor profile 42 years ago

 

You need to subtract the $unit's from $time as per Barand's comment but apparently you don't want to listen/be helped.

Edited by ignace

I declared this variable to above the function... with a value.

 

$date = '2012-09-26 17:25:02';
$postedDateTime = strtotime($date);

 

the output is "Mr. Tharanga added his tutor profile ago" but Barand has mentioned it is working properly.. Just I check it on live.. but the result is same.

Barand please check this again..

 

$date = '2012-09-26 17:25:02';
$postedDateTime = strtotime($date);
//$postedDateTime = date('2012-09-23 09:11:02');
//$postedDateTime = strtotime('2012-09-25 09:11:02');

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':'');
			 }
}
echo 'Mr. Tharanga added his tutor profile ' . time_elapsed_since($postedDateTime) . ' ago';

?>

 

my output is "Mr. Tharanga added his tutor profile ago"

 

NOTE: im trying on local host using wamp server..

 

I got

Now: 2012-09-26 18:00:45
Mr. Tharanga added his tutor profile 35 minutes ago

Note: I added the Now: bit

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.