diff --git a/src/Module/Moderation/BaseUsers.php b/src/Module/Moderation/BaseUsers.php index 14bbd60766..db1588d0bb 100644 --- a/src/Module/Moderation/BaseUsers.php +++ b/src/Module/Moderation/BaseUsers.php @@ -137,7 +137,7 @@ abstract class BaseUsers extends BaseModeration $user['account_type'] = ($user['page_flags_raw'] == 0) ? $account_types[$user['account-type']] : ''; $user['register_date'] = Temporal::getRelativeDate($user['register_date']); - $user['login_date'] = Temporal::getRelativeDate($user['last-activity'], null, false); + $user['login_date'] = Temporal::getRelativeDate($user['last-activity'], false); $user['lastitem_date'] = Temporal::getRelativeDate($user['last-item']); $user['is_admin'] = in_array($user['email'], $adminlist); $user['is_deletable'] = !$user['account_removed'] && intval($user['uid']) != $this->session->getLocalUserId(); diff --git a/src/Util/Temporal.php b/src/Util/Temporal.php index 24d7d7e23d..6a0cd65997 100644 --- a/src/Util/Temporal.php +++ b/src/Util/Temporal.php @@ -26,6 +26,8 @@ use DateTimeZone; use Friendica\Core\Renderer; use Friendica\Database\DBA; use Friendica\DI; +use Friendica\Util\Clock\SystemClock; +use Psr\Clock\ClockInterface; /** * Temporal class @@ -305,19 +307,21 @@ class Temporal * Results relative to current timezone. * Limited to range of timestamps. * - * @param string $posted_date MySQL-formatted date string (YYYY-MM-DD HH:MM:SS) - * @param string $format (optional) Parsed with sprintf() - * @param bool $compare_time Compare date (false) or date and time (true). "true" is default. - * %1$d %2$s ago, e.g. 22 hours ago, 1 minute ago + * @param string|null $posted_date MySQL-formatted date string (YYYY-MM-DD HH:MM:SS) + * @param bool $compare_time Compare date (false) or date and time (true). "true" is default. + * @param ClockInterface|null $clock + * %1$d %2$s ago, e.g. 22 hours ago, 1 minute ago * * @return string with relative date */ - public static function getRelativeDate(string $posted_date = null, string $format = null, bool $compare_time = true): string + public static function getRelativeDate(string $posted_date = null, bool $compare_time = true, ClockInterface $clock = null): string { if (empty($posted_date) || $posted_date <= DBA::NULL_DATETIME) { return DI::l10n()->t('never'); } + $clock = $clock ?? new SystemClock(); + $localtime = $posted_date . ' UTC'; $abs = strtotime($localtime); @@ -325,8 +329,8 @@ class Temporal return DI::l10n()->t('never'); } - $now = time(); - + $now = $clock->now()->getTimestamp(); + if (!$compare_time) { $now = mktime(0, 0, 0, date('m', $now), date('d', $now), date('Y', $now)); $abs = mktime(0, 0, 0, date('m', $abs), date('d', $abs), date('Y', $abs)); @@ -335,7 +339,7 @@ class Temporal $isfuture = false; $etime = $now - $abs; - if ($etime < 1 && $etime >= 0) { + if ($etime >= 0 && $etime < 1) { return $compare_time ? DI::l10n()->t('less than a second ago') : DI::l10n()->t('today'); } @@ -357,15 +361,13 @@ class Temporal foreach ($a as $secs => $str) { $d = $etime / $secs; if ($d >= 1) { - $r = round($d); + $r = floor($d); // translators - e.g. 22 hours ago, 1 minute ago - if (!$format) { - if($isfuture){ - $format = DI::l10n()->t('in %1$d %2$s'); - } - else { - $format = DI::l10n()->t('%1$d %2$s ago'); - } + if($isfuture){ + $format = DI::l10n()->t('in %1$d %2$s'); + } + else { + $format = DI::l10n()->t('%1$d %2$s ago'); } return sprintf($format, $r, (($r == 1) ? $str[0] : $str[1])); diff --git a/tests/src/Util/TemporalTest.php b/tests/src/Util/TemporalTest.php index cfe1af5e23..4181a51fa3 100644 --- a/tests/src/Util/TemporalTest.php +++ b/tests/src/Util/TemporalTest.php @@ -22,6 +22,8 @@ namespace Friendica\Test\src\Util; use Friendica\DI; +use Friendica\Util\Clock\FrozenClock; +use Friendica\Util\DateTimeFormat; use Friendica\Util\Temporal; use PHPUnit\Framework\TestCase; @@ -35,27 +37,46 @@ class TemporalTest extends TestCase */ public function testGetRelativeDate() { - // "never" would should be returned + $clock = new FrozenClock(); + + // "never" should be returned self::assertEquals( - Temporal::getRelativeDate(''), + Temporal::getRelativeDate('', true, $clock), DI::l10n()->t('never') ); // Format current date/time into "MySQL" format - $now = date('Y-m-d H:i:s'); self::assertEquals( - Temporal::getRelativeDate($now), + Temporal::getRelativeDate($clock->now()->format(DateTimeFormat::MYSQL), true, $clock), DI::l10n()->t('less than a second ago') ); // Format current date/time - 1 minute into "MySQL" format - $minuteAgo = date('Y-m-d H:i:s', time() - 60); + $minuteAgo = date('Y-m-d H:i:s', $clock->now()->getTimestamp() - 60); $format = DI::l10n()->t('%1$d %2$s ago'); // Should be both equal self::assertEquals( - Temporal::getRelativeDate($minuteAgo), + Temporal::getRelativeDate($minuteAgo, true, $clock), sprintf($format, 1, DI::l10n()->t('minute')) ); + + $almostAnHourAgoInterval = new \DateInterval('PT59M59S'); + $almostAnHourAgoInterval->invert = 1; + $almostAnHourAgo = (clone $clock->now())->add($almostAnHourAgoInterval); + + self::assertEquals( + Temporal::getRelativeDate($almostAnHourAgo->format(DateTimeFormat::MYSQL), true, $clock), + sprintf($format, 59, DI::l10n()->t('minutes')) + ); + + $anHourAgoInterval = new \DateInterval('PT1H'); + $anHourAgoInterval->invert = 1; + $anHourAgo = (clone $clock->now())->add($anHourAgoInterval); + + self::assertEquals( + Temporal::getRelativeDate($anHourAgo->format(DateTimeFormat::MYSQL), true, $clock), + sprintf($format, 1, DI::l10n()->t('hour')) + ); } }