Skip to content

whereDate() / whereTime() ignore timezone of Carbon/DateTimeInterface values, shifting comparison instant #14939

Description

@marcorieser

Bug description

Builder::whereDate() and Builder::whereTime() (src/Query/Builder.php) accept a DateTimeInterface value. Internally they format the value down to a date-only or time-only string, then reparse it:

$value = Carbon::parse($value->format('Y-m-d')); // whereDate
$value = $value->format('H:i:s'); // whereTime

format() reads the components in the value's own timezone, but the reparse (Carbon::parse, or the raw string in whereTime) uses the app's default timezone (config('app.timezone')). If the passed value is in a different timezone than the app, the calendar digits get reinterpreted as if they were already in the app timezone — silently shifting the represented instant instead of converting it.

How to reproduce

App timezone UTC. Entry has test_date = 2021-11-14 09:00:00 (stored/augmented in UTC).

$value = Carbon::create(2021, 11, 15, 2, 0, 0, 'Europe/Moscow'); // = 2021-11-14 23:00:00 UTC

Entry::query()->whereDate('test_date', $value)->get();
// Expected: matches entries on 2021-11-14 (the UTC calendar date of the instant)
// Actual: matches entries on 2021-11-15 instead

Same issue for whereTime():

$value = Carbon::create(2021, 11, 13, 12, 0, 0, 'Europe/Moscow'); // = 09:00:00 UTC

Entry::query()->whereTime('test_date', $value)->get();
// Expected: matches entries at 09:00:00
// Actual: compares against 12:00:00 instead

Logs

Environment

Environment
Laravel Version: 13.18.1
PHP Version: 8.5.7
Composer Version: 2.10.1
Environment: local
Debug Mode: ENABLED
Maintenance Mode: OFF
Timezone: UTC
Locale: en

Cache
Config: NOT CACHED
Events: NOT CACHED
Routes: NOT CACHED
Views: CACHED

Drivers
Broadcasting: log
Cache: file
Database: sqlite
Logs: stack / single
Mail: log
Queue: sync
Session: file

Storage
public/storage: NOT LINKED

Statamic
Addons: 0
License Key: Not set
Sites: 1
Stache Watcher: Enabled (auto)
Static Caching: Disabled
Version: 6.24.1 PRO

Installation

Fresh statamic/statamic site via CLI

Additional details

  • Only affects passing an explicit DateTimeInterface/Carbon in a non-app timezone; plain date/time strings are unaffected since they're already parsed in the app timezone.
  • Affects the Stache/flat-file query builder (src/Query/Builder.php, consumed by IteratorBuilder) — the Eloquent-backed path (EloquentQueryBuilder) delegates straight to Laravel/DB and isn't affected.
  • Fix + tests in progress on branch fix/where-date-time-timezone.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions