filament icon indicating copy to clipboard operation
filament copied to clipboard

DatePicker subtracts one day when using timezone

Open francoism90 opened this issue 11 months ago • 5 comments

Package

filament/filament

Package Version

v3.2.137

Laravel Version

v11.41.3

Livewire Version

v3.5.12

PHP Version

8.3.4

Problem description

This is the input:

public static function starts(): DatePicker
{
    return DatePicker::make('starts_at')
        ->label(__('Starts at'))
        ->required()
        ->live()
        ->seconds(false)
        ->timezone('Europe/Amsterdam');
}

This is the model caster:

class Ticket extends Model
{
    /**
     * @var array<string, string>
     */
    protected $casts = [
        'starts_at' => 'date:Y-m-d',
    ];
}

When the filled date is 10-02-2025, and you save model changes, it will be saved as 09-02-2025 (day-1). This happens on every save,even when setting a different date.

I know bugs reports exists, but even after appyling the date casting it still happens: https://github.com/filamentphp/filament/issues/5601#issuecomment-1680371753

Removing the timezone method fixes the issue, it also work fine when you set ->timezone('UTC') (same timezone as application). But we need this conversion for international users, and we keep the application as UTC.

If you need more debug information, please let me know.

Thanks.

Expected behavior

Timezone method working

Steps to reproduce

  1. Create datepicker input
  2. Set ->timezone('x')
  3. Submit form

Reproduction repository (issue will be closed if this is not valid)

https://github.com/francoism90/filament-dateinput-timezone

Relevant log output

I don't have a log, if you need a value dump, please let me know.

francoism90 avatar Feb 10 '25 15:02 francoism90

What may be relevant is that the actual database column is datetime (timestamp). At the moment only dates are required, time will be added later. It's fine this is stored as 00:00:00.

Could this be the problem?

francoism90 avatar Feb 10 '25 15:02 francoism90

Yes, I have the same issue as well.

phattarachai avatar Feb 11 '25 06:02 phattarachai

Fairly sure this is because of Daylight saving and your db timezone. so therefore when saving it is saving at the correct date.

tonypartridge avatar Feb 11 '25 15:02 tonypartridge

I filled the Blog Post published_at attribute with 10-10-1973 and gave the timezone to Asia/Dhaka and created a new Blog Post with the instructions in Step to Reproduce (creating a publishes() method with the above code snippet) and reviewed the changes in published_at in the newly created blog post. It's showing the same date:

Image Image

ksaif534 avatar Mar 08 '25 06:03 ksaif534

this issue exists when we use local timezone

when app using UTC and set the field using local timezone. it will save using local timezone value. thats why there is difference

fixed it with this

protected function setFilamentFieldTimezone(string $timezone): void
    {
        /*
         * configure field timezone only when displaying
         */
        DatePicker::configureUsing(function (DatePicker $datePicker) use ($timezone): void {
            if ($datePicker->isReadOnly()) {
                $datePicker->timezone($timezone);
            }
        });

        /*
         * configure field timezone only when displaying
         */
        DateTimePicker::configureUsing(function (DateTimePicker $dateTimePicker) use ($timezone): void {
            if ($dateTimePicker->isReadOnly()) {
                $dateTimePicker->timezone($timezone);
            }
        });

        TextColumn::configureUsing(function (TextColumn $textColumn) use ($timezone): void {
            if ($textColumn->isDateTime() || $textColumn->isDate()) {
                $textColumn->timezone($timezone);
            }
        });
    }```

anditsung avatar May 17 '25 01:05 anditsung

This issue is because the "timezone" feature only really makes sense when using date-times or times, not date-only. Date only is storing a date with a "midnight" time, and midnight in Amsterdam is always the next day to UTC, hence why the day is stored as the day before.

I don't think this specifically is a bug in Filament, we are storing the correct midnight date in UTC based on the timezone you give us.

I do not think you need to use the timezone method at all for non-timed dates, if you are never expecting the date to be stored differently to how the user inputs it.

Please let me know if I'm missing something and I can reopen

danharrin avatar Jun 22 '25 20:06 danharrin