Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Nova Date Time Laravel Package

jagdeepbanga/nova-date-time

jagdeepbanga/nova-date-time provides a simple date and time field for Laravel Nova, making it easy to add date/time selection to resource forms and manage datetime attributes in your admin panel.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a small, single-purpose Nova field package that gives you a combined date + time picker in a single form input. Treat it as a utility field, not a framework — read the source before you rely on it.

Install

composer require jagdeepbanga/nova-date-time

Then register the field's service provider (Nova 3-era packages usually require this explicitly):

// config/app.php
'providers' => [
    // ...
    Jagdeepbanga\NovaDateTime\FieldServiceProvider::class,
],

Run php artisan vendor:publish --tag=nova-date-time if a publish tag exists, and php artisan nova:publish so the compiled assets land in public/vendor/nova-date-time.

Where to look first

  1. vendor/jagdeepbanga/nova-date-time/src/ — the field class. Note the exact namespace and constructor signature; the README may lag behind the code.
  2. resources/js/field.js (or components/) — tells you which JS datepicker it wraps and what props it accepts (format, displayFormat, twelveHourTime, etc.).
  3. dist/js/field.js — the pre-compiled asset that actually ships. If this is stale, the source is irrelevant.

First use case

Drop it into a resource form in place of a plain Text field for something like a scheduled publish time:

use Jagdeepbanga\NovaDateTime\NovaDateTime;

public function fields(Request $request)
{
    return [
        NovaDateTime::make('Publishes At')
            ->rules('required', 'date'),
    ];
}

Make sure the underlying column is a real datetime (not timestamp, which caps at 2038 on MySQL) and that your model casts it:

protected $casts = ['publishes_at' => 'datetime'];

Implementation Patterns

Baseline field with explicit formats

Always set both the storage format and the display format, because the picker's JS format string and PHP's date() format are different languages and the package may pass one straight through to the other:

NovaDateTime::make('Starts At')
    ->format('YYYY-MM-DD HH:mm:ss')     // what the JS picker emits
    ->displayFormat('DD MMM YYYY, HH:mm') // what index/detail show
    ->required()
    ->sortable(),

Timezone handling — be deliberate

Nova's own DateTime field stores UTC and renders in the app timezone via ->timezone(). A 2020 community field frequently does neither. Pick one of these and be consistent:

// Option A: let the app timezone do the work
// config/app.php => 'timezone' => 'UTC', render with ->displayUsing()
NovaDateTime::make('Starts At')
    ->displayUsing(fn ($value) => $value?->timezone(config('app.display_timezone'))->format('M j, Y g:i A')),

// Option B: store local time, document it loudly, never convert

If you need both display and input in a non-UTC zone, pair the field with a Timezone helper or a static Select and convert in the model accessor/mutator rather than fighting the field.

Default to "now" and nullable clearing

NovaDateTime::make('Responded At')
    ->default(fn () => now())
    ->nullable()
    ->hideFromIndex(),

Test the clear button explicitly — custom pickers often emit null on one code path and an empty string on another, and empty string will fail a date rule while null passes.

Resource-wide consistency via a subclass

Since the package has no global config, wrap it once and use your wrapper everywhere:

namespace App\Nova\Fields;

class AppDateTime extends \Jagdeepbanga\NovaDateTime\NovaDateTime
{
    public function __construct($name, $attribute = null, $resolveCallback = null)
    {
        parent::__construct($name, $attribute, $resolveCallback);

        $this->format('YYYY-MM-DD HH:mm:ss')
             ->displayFormat('D, M j Y · H:i')
             ->sortable();
    }
}

This is your single upgrade point if you later swap to Nova's native DateTime field.

Filters and metrics still need plain SQL

The field only affects presentation. Date-range Nova filters work against the raw column:

public function apply(Request $request, $query, $value)
{
    [$from, $to] = explode(' - ', $value);
    return $query->whereBetween('publishes_at', [$from, $to]);
}

Keep filter inputs as Date fields — reusing the picker in filters is usually more trouble than it's worth.

Validation that survives the JS layer

Client-side picker constraints are cosmetic; validate server-side:

NovaDateTime::make('Ends At')
    ->rules('required', 'date', 'after:starts_at'),

Use after_or_equal with ->creationRules() / ->updateRules() when the same column is compared to itself on update.


Gotchas and Tips

  • Nova version compatibility is the big one. This package's last release was September 2020, which predates Nova 4's asset registration changes (Nova::script / Nova::style replacing the old public/vendor convention) and the Nova 4/5 field lifecycle. Verify it against your Nova major version on a scratch resource before committing. If it breaks, Nova ships a native DateTime field in modern versions — migrating is usually the cheaper path than patching.
  • Check dist/ is current. Small packages often ship source changes without recompiling. If the picker doesn't reflect documented props, diff resources/js against dist/js and run the build yourself.
  • Format strings in two languages. format() may feed moment/flatpickr syntax while displayFormat() feeds PHP. Setting one and assuming the other is a common source of "shows fine, saves garbage."
  • Timezone double-conversion. If you also cast in the model and set config/app.php timezone and the picker emits local time, you can silently shift timestamps by hours. Write one test that asserts the exact UTC string in the database after a form save.
  • Asset and browser caching. After composer update, run php artisan nova:publish and hard-refresh; a stale field.js in public/vendor is the most likely cause of "my change did nothing."
  • Sortable on nulls. ->sortable() sorts by the raw column; mixed NULLs sort inconsistently across MySQL/Postgres. Add a COALESCE via ->sortable(fn ($query, $direction) => ...) if it matters.
  • Index truncation. Long date-time strings get clamped in the index view. Prefer displayFormat('Y-m-d H:i') or ->hideFromIndex() and surface the value in detail only.
  • Dusk tests need to bypass the picker. Automating a third-party datepicker is brittle; fill the underlying input with ->type() after ->click(), or skip the UI and test the save path via the Nova API.
  • No dependents and low adoption means edge cases are yours to find. Budget an hour for a smoke test on create, update, clear, and timezone-crossing saves before shipping. Fork it into app/Nova/Fields (or a private vendor path) so a future composer update can't yank your field out from under you.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk