Just a quick note to refine a function that will take a date in the past and return the number of years, months, weeks, days, hours, minutes and seconds.
Why?
Here are some examples of what we want to achieve:
copyraw
Actually we just want the first two words of those strings:1 year 2 months 3 weeks 4 days 5 hours 6 minutes 7 seconds // full string 1 year 3 weeks 5 hours 7 seconds // where shown values are not zero
- 1 year 2 months 3 weeks 4 days 5 hours 6 minutes 7 seconds  // full string
- 1 year 3 weeks 5 hours 7 seconds  // where shown values are not zero
copyraw
3 days ago // where event is 3 days ago or just over but less than 4 days ago 1 week ago // where event is just over 1 week ago but less than 2 weeks ago
- 3 days ago  // where event is 3 days ago or just over but less than 4 days ago
- 1 week ago  // where event is just over 1 week ago but less than 2 weeks ago
How?
I know there are so many examples out there that do this perhaps better but this one I understand and can customize to fit my needs.
This PHP function accepts as parameter a SQL date (or date format that strtotime() can convert) and outputs the largest unit (for example "1 year" not "1 year 2 months 3 days, etc...").
copyraw
function getTimeAgo($p_Date) {
// get seconds ago
$v_Seconds = strtotime('now') - strtotime($p_Date);
// set unit labels
$a_UnitLabels = array('year','month','week','day','hour','minute','second');
// set unit values
$a_UnitValues = array(
floor($v_Seconds / 31536000),
floor(($v_Seconds % 31536000) / 2592000),
floor(($v_Seconds % 2592000) / 604800),
floor(($v_Seconds % 604800) / 86400),
floor(($v_Seconds % 86400) / 3600),
floor(($v_Seconds % 3600) / 60),
floor($v_Seconds % 60),
);
// initiate array (for array_slice)
$a_UnitPairs = array();
// loop concatenating unit value to its label
for($i=0;$i<count($a_UnitLabels);$i++){
// pair up if greater than zero
$v_Str = $a_UnitValues[$i]>0 ? $a_UnitValues[$i].' '.$a_UnitLabels[$i] : '';
// grammar for plural/singular (should always be a positive number)
$v_Str .= $a_UnitValues[$i]>1 ? 's' : '';
// only add to array if not empty/zero
if($v_Str!='') $a_UnitPairs[] = $v_Str;
}
// take first item of array (round up to largest unit)
$v_ReturnStr = $a_UnitPairs[0].' ago';
// return
return $v_ReturnStr;
}
- function getTimeAgo($p_Date) {
- // get seconds ago
- $v_Seconds = strtotime('now') - strtotime($p_Date);
- // set unit labels
- $a_UnitLabels = array('year','month','week','day','hour','minute','second');
- // set unit values
- $a_UnitValues = array(
- floor($v_Seconds / 31536000),
- floor(($v_Seconds % 31536000) / 2592000),
- floor(($v_Seconds % 2592000) / 604800),
- floor(($v_Seconds % 604800) / 86400),
- floor(($v_Seconds % 86400) / 3600),
- floor(($v_Seconds % 3600) / 60),
- floor($v_Seconds % 60),
- );
- // initiate array (for array_slice)
- $a_UnitPairs = array();
- // loop concatenating unit value to its label
- for($i=0;$i<count($a_UnitLabels);$i++){
- // pair up if greater than zero
- $v_Str = $a_UnitValues[$i]>0 ? $a_UnitValues[$i].' '.$a_UnitLabels[$i] : '';
- // grammar for plural/singular (should always be a positive number)
- $v_Str .= $a_UnitValues[$i]>1 ? 's' : '';
- // only add to array if not empty/zero
- if($v_Str!='') $a_UnitPairs[] = $v_Str;
- }
- // take first item of array (round up to largest unit)
- $v_ReturnStr = $a_UnitPairs[0].' ago';
- // return
- return $v_ReturnStr;
- }
Usage
copyraw
$v_Str = getTimeAgo('2019-05-16 19:30:00');
// If (at time of print) this date is 17 minutes and 5 seconds ago
// then $v_Str = "17 minutes ago"
- $v_Str = getTimeAgo('2019-05-16 19:30:00');
- // if (at time of print) this date is 17 minutes and 5 seconds ago
- // then $v_Str = "17 minutes ago"
Or how about
copyraw
$v_Str = getTimeAgo('-1 week 2 days 4 hours 2 seconds');
// yields "1 week ago"
$v_Str = getTimeAgo('last Monday');
// yields "3 days ago" (it's Thursday)
$v_Str = getTimeAgo('first day of this month');
// yields "15 days ago" (it's the 16th)
- $v_Str = getTimeAgo('-1 week 2 days 4 hours 2 seconds');
- // yields "1 week ago"
- $v_Str = getTimeAgo('last Monday');
- // yields "3 days ago" (it's Thursday)
- $v_Str = getTimeAgo('first day of this month');
- // yields "15 days ago" (it's the 16th)
The same PHP function as above but somewhat minimized
copyraw
function getTimeAgo($p){
$s = strtotime('now') - strtotime($p);
$a1 = array('year','month','week','day','hour','minute','second');
$a2 = array(
floor($s/31536000),
floor(($s%31536000)/2592000),
floor(($s%2592000)/604800),
floor(($s%604800)/86400),
floor(($s%86400)/3600),
floor(($s%3600)/60),
floor($s%60),
);
for($i=0;$i<count($a1);$i++){
$str = $a2[$i]>0 ? $a2[$i].' '.$a1[$i] : '';
$str .= $a2[$i]>1 ? 's' : '';
if($str!='') break;
}
return $str.' ago';
}
- function getTimeAgo($p){
- $s = strtotime('now') - strtotime($p);
- $a1 = array('year','month','week','day','hour','minute','second');
- $a2 = array(
- floor($s/31536000),
- floor(($s%31536000)/2592000),
- floor(($s%2592000)/604800),
- floor(($s%604800)/86400),
- floor(($s%86400)/3600),
- floor(($s%3600)/60),
- floor($s%60),
- );
- for($i=0;$i<count($a1);$i++){
- $str = $a2[$i]>0 ? $a2[$i].' '.$a1[$i] : '';
- $str .= $a2[$i]>1 ? 's' : '';
- if($str!='') break;
- }
- return $str.' ago';
- }
If you want the first 4 words but minified (eg. "1 week and 2 days ago"):
copyraw
function getTimeAgo($p) {
$s = strtotime('now') - strtotime($p);
$a1 = array('year','month','week','day','hour','minute','second');
$a2 = array(
floor($s / 31536000),
floor(($s % 31536000) / 2592000),
floor(($s % 2592000) / 604800),
floor(($s % 604800) / 86400),
floor(($s % 86400) / 3600),
floor(($s % 3600) / 60),
floor($s % 60),
);
for($i=0;$i<count($a1);$i++){
$v = $a2[$i]>0 ? $a2[$i].' '.$a1[$i] : '';
$v .= $a2[$i]>1 ? 's' : '';
if($v!='') $a3[] = $v;
}
return implode(' and ', array_slice($a3,0,2)).' ago';
}
- function getTimeAgo($p) {
- $s = strtotime('now') - strtotime($p);
- $a1 = array('year','month','week','day','hour','minute','second');
- $a2 = array(
- floor($s / 31536000),
- floor(($s % 31536000) / 2592000),
- floor(($s % 2592000) / 604800),
- floor(($s % 604800) / 86400),
- floor(($s % 86400) / 3600),
- floor(($s % 3600) / 60),
- floor($s % 60),
- );
- for($i=0;$i<count($a1);$i++){
- $v = $a2[$i]>0 ? $a2[$i].' '.$a1[$i] : '';
- $v .= $a2[$i]>1 ? 's' : '';
- if($v!='') $a3[] = $v;
- }
- return implode(' and ', array_slice($a3,0,2)).' ago';
- }
When could I possibly want to do this? Well I've previously used this for password change reminders but on this occasion for a listing of reviews laid out as per the following screenshot:

Category: Personal Home Page :: Article: 679



Add comment