gerenuk/filament-utc-dts
A Filament package for UTC date-times that stores timestamps in UTC while displaying them in the user’s local timezone. Includes form fields and table columns to keep date/time handling consistent across Laravel admin panels.
composer require gerenuk/filament-utc-dts
Gerenuk\FilamentUtcDts\FilamentUtcDtsPlugin or similar). The only integration point that matters is the Panel registration.app/Providers/Filament/AdminPanelProvider.php:
use Gerenuk\FilamentUtcDts\FilamentUtcDtsPlugin;
public function panel(Panel $panel): Panel
{
return $panel
->plugin(FilamentUtcDtsPlugin::make());
}
php artisan optimize:clear
php artisan filament:optimize
php artisan vendor:publish --provider="Gerenuk\FilamentUtcDts\FilamentUtcDtsServiceProvider"
Check the README for the exact tag; small packages often support a short tag like --tag="filament-utc-dts-config".First use case: an admin/ops panel used by staff who cross-reference UTC timestamps from logs, cron schedules, created_at columns, and incident timelines. A ambient UTC clock in the topbar removes the constant "what time is it in UTC?" tab-switching. It is also a cheap sanity anchor for teams whose Filament tables/forms display times in the app timezone (config('app.timezone')) rather than UTC.
Where to look first in the repo: src/ for the plugin and service provider, then the single Blade view (likely under resources/views/) to see which render hook it targets (panels::topbar.end, panels::user-menu.before, etc.). That hook location determines where the indicator appears and whether you can relocate it without forking.
Single-panel registration. Register on one panel to limit blast radius. The clock is decoration; it should not appear on customer-facing panels where UTC is irrelevant or confusing.
Multi-panel apps. If you run AdminPanelProvider and StaffPanelProvider, either register the plugin in both providers, or extract a BasePanelProvider trait that applies the plugin plus your common theme. Keep the plugin call after ->colors()/->brandName() so it inherits the panel's CSS variables.
Conditional visibility. Registration happens at boot, so gate it with env or an auth check in the provider when you only want it during incidents or for admins:
if (app()->environment(['local', 'staging']) || auth()->user()?->isAdmin()) {
$panel->plugin(FilamentUtcDtsPlugin::make());
}
Be careful calling auth() in a panel provider — it runs on the request, so this works, but avoid it in console commands where the guard is empty.
Pair it with consistent timezone handling. The indicator is display-only; it does not convert anything. Treat it as a visual contract: if the topbar says UTC, make sure DateTimePicker, Table date columns, and TextColumn::dateTime() either use ->timezone('UTC') explicitly or clearly say they are in app timezone. Mismatched surfaces are the most common source of confusion this package will expose, not cause.
Custom placement. If the package hardcodes a topbar hook and you need the clock in the user menu, don't hack the vendor view — register your own render hook:
use Filament\Support\Facades\FilamentView;
use Illuminate\Support\Facades\Blade;
FilamentView::registerRenderHook(
'panels::user-menu.before',
fn () => Blade::render('<x-filament-utc-dts::indicator />'),
);
Verify the view namespace first; if the package doesn't expose one, copy the partial into your app and reference your own Livewire widget.
Styling to fit the panel. Topbars are tight. Prefer a compact format (H:i or H:i:s with a small UTC label) over a full date. If the view exposes a format config key, set it in config/filament-utc-dts.php; otherwise override with CSS custom properties or a published view.
Testing.
$this->actingAs($admin)
->get('/admin')
->assertSee('UTC');
assertSee after ->call('refresh') or a timer tick.Dependency hygiene. Pin ^1.0 (or the exact release) in composer.json, add it to Dependabot/Renovate, and keep it as a leaf dependency — never let domain code import its namespace, so removing it later is a one-line provider change.
It does not convert timestamps. The package adds an indicator, not a timezone layer. Anyone reading a Filament table will still see whatever the column renders. Set ->timezone() on Filament date/time components deliberately and consider a consistent config('app.display_timezone') if you need one.
Verify the clock uses UTC, not the app timezone. Server-side implementations sometimes call now() and rely on config('app.timezone'). Check the source for now('UTC') / Carbon::now('UTC') versus a bare now(). If it's wrong, either set a package config if provided or shadow the view.
Client-side rendering and caching. If the indicator is Alpine/JS driven, it won't appear in assertSee() and it can be deferred. Check wire:ignore behavior and whether Filament's ->spa() mode re-mounts it on navigation. A static UTC label backed by Alpine is more robust than a fully client-side time string.
Topbar layout on mobile. Filament hides many topbar items under a breakpoint. Expect the indicator to disappear or crowd the user menu on small screens. Add a responsive wrapper (hidden md:flex) in a published view or hide the plugin on narrow viewports via CSS.
Caching after install. Filament aggressively caches panel components. If the indicator doesn't show after adding the plugin, run php artisan filament:optimize-clear (or optimize:clear) and hard-refresh. This accounts for most "it doesn't work" reports.
Low adoption surface. With 5 stars and zero dependents, treat the package as unaudited: read composer.json for the Filament major it supports (^3 vs ^4), skim src/ for anything beyond a view and a plugin, and confirm MIT licensing files are present. Forking a 200-line plugin is cheap if maintenance stalls.
Extension points are likely thin. Small packages often ship no config and no published views. Plan B is always the same: register your own render hook with a Blade partial or a tiny Livewire component using now('UTC')->format('H:i'). That is roughly ten lines and gives you total control over placement, format, and accessibility.
Accessibility. Ensure the indicator has an aria-label or title that spells out "Coordinated Universal Time" and, ideally, the user's local time in a tooltip. A bare 14:32 in a topbar is ambiguous to anyone who doesn't already know it's UTC.
Debugging checklist. composer show gerenuk/filament-utc-dts to confirm install, php artisan about to confirm provider discovery, php artisan route:list | grep filament to confirm the panel boots, then view-source the panel to locate the rendered hook output. If nothing renders, the plugin class name or panel registration is almost always the culprit.
How can I help you explore Laravel packages today?