function toRelativePastTime(DateTimeImmutable $past): string
{
$now = new DateTimeImmutable('now', new DateTimeZone('UTC'));
$delta = abs($now->getTimestamp() - $past->getTimestamp());
$seconds = $delta;
$minutes = intdiv($seconds, 60);
$hours = intdiv($seconds, 3600);
$days = intdiv($seconds, 86400);
if ($seconds < 60) {
return $seconds === 1 ? "one second ago" : "$seconds seconds ago";
}
if ($seconds < 3600) {
return $minutes === 1 ? "a minute ago" : "$minutes minutes ago";
}
if ($seconds < 86400) {
return $hours === 1 ? "an hour ago" : "$hours hours ago";
}
if ($seconds < 2592000) { // 30 days
return $days === 1 ? "yesterday" : "$days days ago";
}
if ($seconds < 31104000) { // 12 months
$months = intdiv($days, 30);
return $months <= 1 ? "a month ago" : "$months months ago";
}
$years = intdiv($days, 365);
return $years <= 1 ? "a year ago" : "$years years ago";
}
function test(float $hoursAgo): void
{
$secondsAgo = (int)round($hoursAgo * 3600);
$past = (new DateTimeImmutable('now', new DateTimeZone('UTC')))
->sub(new DateInterval("PT{$secondsAgo}S"));
echo toRelativePastTime($past) . PHP_EOL;
}
test(0.01); // 36 seconds ago
test(0.2); // 12 minutes ago
test(3); // 3 hours ago
test(25); // yesterday
test(360); // 15 days ago
test(1239); // a month ago
test(2239); // 3 months ago
test(8760); // a year ago
test(98763); // 11 years ago
/*
run:
36 seconds ago
12 minutes ago
3 hours ago
yesterday
15 days ago
a month ago
3 months ago
a year ago
11 years ago
*/