diff --git a/README.md b/README.md index 54ea57d..eac9239 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,8 @@ Last edited: {{ post.updatedAt|time_diff }} Event date: {{ event.date|time_diff }} Read time: {{ post.readTimeInSeconds|duration }} + +Age: {{ user.birthdate|age }} ``` Want to see it used in a screencast 🎥? Check out SymfonyCasts: https://symfonycasts.com/screencast/symfony-doctrine/ago @@ -50,6 +52,16 @@ Duration formatting: {{ someDurationInSeconds|duration }} {# 2 minutes #} ``` +Age formatting: + +```twig +{# with filter: #} +Age: {{ user.birthdate|age }} {# Age: 30 years old #} + +{# ... or use the equivalent function: #} +Age: {{ age(user.birthdate) }} {# Age: 30 years old #} +``` + ### Service You can also format dates and durations in your services/controllers by autowiring/injecting the @@ -68,6 +80,8 @@ public function yourAction(DateTimeFormatter $dateTimeFormatter) $readTime = $dateTimeFormatter->formatDuration(64); // or $entity->readTimeInSeconds() + $ageTime = $dateTimeFormatter->formatAge($someDate, $toDate); // $toDate parameter is optional and defaults to "now" + return $this->json([ // ... 'published_at' => $agoTime, // 2 years ago @@ -87,6 +101,8 @@ the locale: {{ someDateTimeVariable|time_diff(locale='es') }} {{ someDurationInSeconds|duration(locale='es') }} + +{{ someDateTimeVariable|age(locale='es') }} ``` ## Tests diff --git a/src/DateTimeFormatter.php b/src/DateTimeFormatter.php index 1195bcf..2203326 100644 --- a/src/DateTimeFormatter.php +++ b/src/DateTimeFormatter.php @@ -89,6 +89,22 @@ public function formatDuration(float $seconds, string $locale = null): string return $this->translator->trans('duration.none', [], 'time', $locale); } + /** + * Returns a formatted age for the given from and to datetimes. + */ + public function formatAge( + int|string|\DateTimeInterface $from, + int|string|\DateTimeInterface $to = null, + string $locale = null + ): string { + $from = self::formatDateTime($from); + $to = self::formatDateTime($to); + + $diff = $from->diff($to); + + return $this->translator->trans('age', ['%count%' => $diff->y], 'time', $locale); + } + private static function formatDateTime(int|string|\DateTimeInterface|null $value): \DateTimeInterface { if ($value instanceof \DateTimeInterface) { diff --git a/src/Twig/Extension/TimeExtension.php b/src/Twig/Extension/TimeExtension.php index da96a95..a25ae64 100644 --- a/src/Twig/Extension/TimeExtension.php +++ b/src/Twig/Extension/TimeExtension.php @@ -25,6 +25,11 @@ public function getFunctions(): array [DateTimeFormatter::class, 'formatDiff'], ['is_safe' => ['html']] ), + new TwigFunction( + 'age', + [DateTimeFormatter::class, 'formatAge'], + ['is_safe' => ['html']] + ), ]; } @@ -46,6 +51,11 @@ public function getFilters(): array [DateTimeFormatter::class, 'formatDuration'], ['is_safe' => ['html']] ), + new TwigFilter( + 'age', + [DateTimeFormatter::class, 'formatAge'], + ['is_safe' => ['html']] + ), ]; } } diff --git a/translations/time.en.xliff b/translations/time.en.xliff index fefa90f..118d9b9 100644 --- a/translations/time.en.xliff +++ b/translations/time.en.xliff @@ -74,6 +74,10 @@ duration.none < 1 second + + age + 1 year old|%count% years old + diff --git a/translations/time.fr.xliff b/translations/time.fr.xliff index c7074ea..15cce18 100644 --- a/translations/time.fr.xliff +++ b/translations/time.fr.xliff @@ -74,6 +74,10 @@ duration.none < 1 seconde + + age + 1 an|%count% ans +