Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

JoshP's avatar
Level 7

Constrain query by relation's timezone?

Hi there!

I have an Event model, a Customer model, and Location model. Events have a customer_id and a location_id. Locations have a customer_id and a timezone.

Currently, I’m grabbing all events with their location relation, then only after getting those, filtering down the collection of events by the event start date translated into the location’s timezone.

Looks basically like this

$allEvents = Event::where('customer_id', $customer->getId())
    ->with('location')
    ->get();

$events = $allEvents->filter(function($event) {
    $start = $event->start_date->tz($event->location->getTimezone())->toDateString();
    $today = Carbon::now()->tz($event->location->getTimezone())->toDateString;

    return $start === $today;
});

This is not ideal, as the number of events will continue to grow.

Is there a way for me to query the events by start_date, but using the location relation's TZ version instead of the UTC version stored on the event? Kind of feels like a cart-before-the-horse issue, but figured I'd ask ;)

0 likes
2 replies
fylzero's avatar

@joshp There is whereHas but it wouldn't help in this case since what you'd want is to make a comparison based on the data it is looking up.

What you're doing actually doesn't sound horribly inefficient, at least you are having PHP crunch the data instead of writing a bad N+1 query. You are also slimming down the data set based on customer_id so it isn't really that bad imo.

1 like
JoshP's avatar
Level 7

@fylzero In my case, for this particular view, I’m just showing the events scheduled for ‘today’. But of course, ‘today’ means something different depending on where you’re loading the view.

E.g., today, there is only one event scheduled, but I've loaded over 8,000 models into memory. I'm only passing the one to the view, but it's still wicked inefficient, and will only get more so.

Looking into the CONVERT_TZ() mysql function, and will see if I can build more of a raw query to get what I'm after.

Please or to participate in this conversation.