0

Alright so I have two dates, the first being when a user was Last Active, and the second being the current DateTime. I can calculate the difference between these two dates by using the DateTime::diff function.

$last_active = new DateTime($user['last_active']);
$current_date = new DateTime();
$interval = $last_active->diff($current_date);

This accurately gives me the difference between the two dates. However, I am at a lost as to how I should use this to format the string in this way I need it (of course based on how many days have passed):

"Today", "1 days", "1 week", "2 weeks and 2 days", "1 month 3 weeks and 2 days"

That sort of thing, if you need more of an explanation please make a comment requesting it. I really need this and I don't know how to implement it without making a million if statements, and no one wants to do that. Any help is appreciated.

Jertyu
  • 105
  • 8
  • You could maintain a table with two columns for the start and end of a given _range_ of date differences. Associated with each such range would be one of the labels you showed us in your question. Then, you would only need to do a lookup of the range against the table to fetch the appropriate label. – Tim Biegeleisen Apr 24 '19 at 17:02
  • 1
    You could use a library like Carbon: https://carbon.nesbot.com/docs/, which extends PHP's built-in DateTime classes to provide functionality like this. – Chris White Apr 24 '19 at 17:08
  • Unfortunately I am not authorized to implement a new column, or to use a new library. – Jertyu Apr 24 '19 at 17:15

1 Answers1

1

You will need to do some counting, no way to skip that, you'll just have to keep it as clear as possible while still maintaining a valid result in all situations (e.g. avoid getting strings like "1 days").

I'd suggest starting from the following snippet written on php.net by acrion@gmail.com:

function pluralize( $count, $text )
{
    return $count . ( ( $count == 1 ) ? ( " $text" ) : ( " ${text}s" ) );
}

function ago( $datetime )
{
    $interval = date_create('now')->diff( $datetime );
    $suffix = ( $interval->invert ? ' ago' : '' );
    if ( $v = $interval->y >= 1 ) return pluralize( $interval->y, 'year' ) . $suffix;
    if ( $v = $interval->m >= 1 ) return pluralize( $interval->m, 'month' ) . $suffix;
    if ( $v = $interval->d >= 1 ) return pluralize( $interval->d, 'day' ) . $suffix;
    if ( $v = $interval->h >= 1 ) return pluralize( $interval->h, 'hour' ) . $suffix;
    if ( $v = $interval->i >= 1 ) return pluralize( $interval->i, 'minute' ) . $suffix;
    return pluralize( $interval->s, 'second' ) . $suffix;
}

Source

So you'd need something like that:

function pluralize( $count, $text )
{
    return $count . ( ( $count == 1 ) ? ( " $text" ) : ( " ${text}s" ) );
}

function ago( $datetime )
{
    $interval = date_create('now')->diff( $datetime );
    $suffix = ( $interval->invert ? ' ago' : '' );
    if ( $v = $interval->y >= 1 ) return pluralize( $interval->y, 'year' ) . $suffix;
    if ( $v = $interval->m >= 1 ) return pluralize( $interval->m, 'month' ) . $suffix;
    if ( $v = $interval->d >= 1 ) return pluralize( $interval->d, 'day' ) . $suffix;
    if ( $v = $interval->h >= 1 ) return pluralize( $interval->h, 'hour' ) . $suffix;
    if ( $v = $interval->i >= 1 ) return pluralize( $interval->i, 'minute' ) . $suffix;
    return pluralize( $interval->s, 'second' ) . $suffix;
}

$last_active = new DateTime($user['last_active']);
$interval = pluralize($last_active);

This will work both for positive and negative differences, though if you prefer avoiding the "ago" suffix you can freely remove it.

Dejan
  • 21
  • 4