Search code examples
phpschedulephp-carbon

Is my shop currently open? using Carbon


I'm trying the following:

I have two models: Pub and Schedule, that stores different schedules of a given pub. For this reason the relation between this two models is 1 pub->N schedules:

Pub:

/**
 * @return \Illuminate\Database\Eloquent\Relations\HasMany
 */
public function pubSchedules()
{
    return $this->hasMany(Schedule::class);
}

Schedule:

/**
 * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
 */
public function pub()
{
    return $this->belongsTo(Pub::class);
}

The table "schedules" has the following fields:

id|pub_id|week_day|opening_time|closing_time

For example, for pub wit id =303, we have the following schedule

id| pub_id|week_day|opening_time|closing_time '9', '303', '5', '00:00:00', '02:30:00' '10', '303', '5', '10:30:00', '13:30:00' '11', '303', '5', '20:00:00', '23:59:00'

I'm trying to do a function to know if a given pub is currently open or not, but as I don't know very much about Carbon I'm having some problems to figure out.

I'd like to know how can I compare the current time with the different opening and closing times of a given pub during the day, and know if current time is inside or not an interval of time the pub is open.

I tried this (I want function return a message "open/closed"):

(rough version)

public function isPubCurrentlyOpen(Pub $pub)
{
    $dayOfWeek = Carbon::now()->dayOfWeek;

    $schedules = Schedule::where([
        ['pub_id', $pub->id ],
        ['week_day', $dayOfWeek],
    ])->get();

    foreach($schedules as $schedule)
    {
        if(var_dump($dayOfWeek->between($schedule->opening_time, $schedule->closing_time))){
            return "Open";
        }

    }
}

Please, could you help me? Thanks!!


Solution

  • The following should do the trick:

    $isOpen = 
        // check if day of week matches
        Carbon::now()->dayOfWeek === $schedule->week_day &&
        // check if current time is greater than or equal than today's opening time
        Carbon::now()->gte(Carbon::now()->setTimeFromTimeString($schedule->opening_time)) &&
        // check if current time is less than or equal than today's closing time
        Carbon::now()->lte(Carbon::now()->setTimeFromTimeString($schedule->closing_time));
    

    UPDATE: as suggested by Thomas below, you can simplify the code by using the between method:

    $isOpen = 
        Carbon::now()->dayOfWeek === $schedule->week_day &&
        Carbon::now()->between(
          Carbon::now()->setTimeFromTimeString($schedule->opening_time),
          Carbon::now()->setTimeFromTimeString($schedule->closing_time)
        );