busayo/laravel-yearly
A lightweight Laravel package for working with yearly cycles and annual date logic. It offers helpers for year-based queries, annual date ranges, and recurring yearly events, making calendar-year data easier to handle in your models and application.
The package is a single-purpose helper: it renders a copyright year (or year range) that stays current without you editing a footer every January. Treat it as a 20-line convenience, not infrastructure.
composer require busayo/laravel-yearly
config/app.php:'providers' => [
// ...
Busayo\Yearly\YearlyServiceProvider::class,
],
If the README mentions a facade, add it to aliases in the same file.
php artisan vendor:publish --provider="Busayo\Yearly\YearlyServiceProvider"
Look first at vendor/busayo/laravel-yearly/src/ — the whole package is one provider plus one helper/directive class. Read it before wiring it in; you need to know the exact call signature (helper name, Blade directive, or facade method) since the 2015 README may not match modern expectations.
First use case: your layout footer.
<footer>
© {{ yearly() }} Acme Inc. All rights reserved.
</footer>
If your site launched in 2012, you want © 2012–2026, so set the start year in the published config rather than hardcoding it in the template.
Inline helper in a single layout. Keep it in resources/views/layouts/app.blade.php only. There is no reason to sprinkle it across partials.
View composer for anything non-trivial. If you need formatting variants (short year, full range, per-entity copyright holders), don't bend the package — wrap it:
// app/Providers/AppServiceProvider.php
View::composer('layouts.app', function ($view) {
$view->with('copyright', sprintf(
'© %s–%s Acme Inc.',
config('site.copyright_start', 2012),
now()->year
));
});
Testing. Freeze time so your footer assertion is stable:
use Illuminate\Support\Carbon;
public function test_footer_shows_current_year()
{
Carbon::setTestNow(Carbon::create(2026, 1, 1, 0, 0, 1));
$this->get('/')->assertSee('2026');
Carbon::setTestNow();
}
If the package caches the rendered year at boot, this test will fail on a long-running process — that's your signal to swap to now()->year.
Integration tip — mail and PDF templates. Any Blade-rendered footer (invoices, terms pages, PDF exports) is a legitimate target. For queued mail, remember the view renders at send time, not at dispatch time; if a job sits in the queue across New Year you'll get the old year. Acceptable for a copyright line.
Migration path. If you already require Laravel 5.5+, the package has no advantage over a Blade component or {{ now()->year }}. Migrate by replacing the directive with now()->year in the layout, deleting the provider line, and running composer remove busayo/laravel-yearly.
composer require will likely fail on platform constraints; you'd need --ignore-platform-reqs, which is a bad trade for a footer string.config/app.php provider entry is the number one "class not found" / "directive not defined" cause. If you see Method [yearly] does not exist, check the provider first.Carbon::now(), which respects config/app.php's timezone. A copyright year in UTC vs a NZ app timezone can disagree for ~13 hours around New Year. Pick one and be consistent; for legal footers, UTC is the safer default.© 2026 and © 2012–2026 are different claims. The start year should come from config or a DB-backed setting, not a value buried in the vendor package. Never let the package decide your founding year.php artisan serve in a dev loop can hold a booted value across midnight on Dec 31. Cosmetic, but it will confuse you in a late-night deploy. now()->year evaluated at render time is immune.php artisan tinker then call the helper directly to confirm registration before blaming the template. Clear config:cache after publishing config — the classic reason a start-year change "did nothing".CopyrightPresenter class or a Blade component. That is 15 lines and will outlive this package.How can I help you explore Laravel packages today?