Installation:
composer require knplabs/knp-time-bundle
If not using Symfony Flex, manually enable the bundle in config/bundles.php:
return [
// ...
Knp\Bundle\TimeBundle\KnpTimeBundle::class => ['all' => true],
];
First Use Case: Display a human-readable time difference in Twig:
{{ post.updatedAt|time_diff }} {# Output: "5 minutes ago" #}
Check Configuration:
Verify default settings in config/packages/knp_time.yaml (e.g., default_locale, formats).
Time Differences in Twig:
|time_diff or |ago for past/future dates:
{{ event.date|time_diff }} {# "in 3 days" #}
{{ post.createdAt|ago }} {# "2 hours ago" #}
time_diff(someDate, 'F j, Y').Duration Formatting:
{{ post.readTimeInSeconds|duration }} {# "1 minute 30 seconds" #}
duration(seconds, 2) (e.g., "1m 30s").Age Calculation:
{{ user.birthdate|age }} {# "30 years old" #}
age() function in Twig or KnpTime::age() in PHP.PHP Integration:
KnpTime service in controllers/services:
$timeDiff = $this->get('knp_time')->diff($dateTime);
$duration = $this->get('knp_time')->duration($seconds);
Translation:
ago, in, years old).translations/messages.{locale}.yml:
knp_time:
ago: "vor"
in: "in"
Doctrine Entities:
Use with DateTime fields directly in Twig templates.
Example:
// Entity
#[ORM\Column(type: 'datetime')]
private $publishedAt;
{{ article.publishedAt|time_diff }} {# "yesterday" #}
API Responses:
Format dates in JSON responses using Symfony’s Serializer with custom normalizers:
# config/packages/serializer.yaml
Knp\Bundle\TimeBundle\Serializer\TimeDiffNormalizer:
format: 'time_diff'
Custom Formats:
Extend formats in config/packages/knp_time.yaml:
knp_time:
format: 'F j, Y \a\t g:i a' {# "January 1, 2023 at 2:30 pm" #}
Locale Mismatches:
default_locale in knp_time.yaml matches your app’s locale.{{ app.request.locale }} in Twig to confirm active locale.Timezones:
DateTime object’s timezone. Use setTimezone() if needed:
$dateTime->setTimezone(new \DateTimeZone('UTC'));
Future Dates:
|time_diff works for future dates but defaults to "in X" phrasing. Override translations if needed.Caching:
php bin/console cache:clear
Edge Cases:
0 seconds. Handle in templates:
{% if post.readTimeInSeconds > 0 %}
{{ post.readTimeInSeconds|duration }}
{% else %}
Instant!
{% endif %}
Check Available Filters: Dump Twig filters to verify registration:
{{ dump(_twig_filters) }}
Look for time_diff, ago, duration, and age.
Log Time Calculations:
Debug DateTime objects in PHP:
\Log::debug('DateTime:', ['date' => $dateTime, 'timezone' => $dateTime->getTimezone()]);
Translation Debugging: Use Symfony’s translation dumper:
php bin/console debug:translation knp_time
Custom Time Diff Logic:
Extend the TimeDiff class:
// src/Service/CustomTimeDiff.php
use Knp\Time\TimeDiff;
class CustomTimeDiff extends TimeDiff {
public function getDiffString(\DateTimeInterface $dateTime): string {
// Custom logic
return parent::getDiffString($dateTime);
}
}
Register as a service:
# config/services.yaml
Knp\Bundle\TimeBundle\Twig\Extension\TimeExtension:
arguments:
$timeDiff: '@custom_time_diff'
Add New Duration Units:
Modify the Duration class or create a decorator:
// src/Service/CustomDuration.php
use Knp\Time\Duration;
class CustomDuration extends Duration {
protected function getUnits(): array {
return array_merge(parent::getUnits(), ['decades' => 36525]);
}
}
Twig Extensions:
Add custom filters/functions to TimeExtension:
// src/Twig/CustomTimeExtension.php
use Knp\Bundle\TimeBundle\Twig\Extension\TimeExtension;
class CustomTimeExtension extends TimeExtension {
public function getFunctions() {
return array_merge(parent::getFunctions(), [
new \Twig\TwigFunction('custom_duration', [$this->duration, 'format']),
]);
}
}
Register the extension in services.yaml.
Configuration Overrides: Dynamically adjust formats per environment:
# config/packages/knp_time.yaml
when@prod:
knp_time:
format: 'Y-m-d' {# Simpler format in production #}
How can I help you explore Laravel packages today?