### Install and migrate Opening Hours for Laravel Source: https://github.com/roundly-consulting/opening-hours-for-laravel/blob/main/README.md Install the package via Composer, publish the migrations, and run them. Requires PHP 8.4, Laravel 12 or 13, and SQLite, PostgreSQL, or MySQL. Set OPENING_HOURS_KEY_TYPE to 'uuid' or 'ulid' before migrating if models use UUID or ULID keys. ```bash composer require roundly-consulting/opening-hours-for-laravel php artisan vendor:publish --tag="opening-hours-migrations" php artisan migrate ``` -------------------------------- ### Generate bookable slots with busy period provider Source: https://github.com/roundly-consulting/opening-hours-for-laravel/blob/main/README.md Create an EloquentBusyPeriodProvider from an Appointment query, then get free 30-minute slots between two dates with a 120-minute minimum notice. ```php use RoundlyConsulting\OpeningHours\Availability\Providers\EloquentBusyPeriodProvider; $busy = EloquentBusyPeriodProvider::for(Appointment::query())->columns(start: 'starts_at', end: 'ends_at'); $slots = $hours->availability() ->withBusyPeriods($busy) ->minNotice(minutes: 120) ->slots('2026-10-12', '2026-10-16')->duration(30)->get(); // free 30-minute slots ``` -------------------------------- ### Sync opening hours and query availability Source: https://github.com/roundly-consulting/opening-hours-for-laravel/blob/main/README.md Sync weekly hours and yearly exceptions, add one-off exceptions, and query open status, next close time, and formatted hours for specific dates. Overnight ranges end on the following day; exceptions with a date like '12-25' apply every year. ```php use RoundlyConsulting\OpeningHours\Facades\OpeningHours; OpeningHours::sync($clinic, [ 'timezone' => 'Europe/Bratislava', 'week' => [ 'monday' => ['08:00-12:00', '13:00-17:00'], 'friday' => ['08:00-15:00'], 'saturday' => ['22:00-03:00'], // overnight: ends 03:00 on Sunday ], 'exceptions' => [['date' => '12-25', 'label' => 'Christmas']], // every year, closed ]); OpeningHours::exceptions($clinic)->closed('2026-10-16', label: 'Staff training'); $hours = OpeningHours::for($clinic); $hours->isOpen(); // right now $hours->nextClose(); // ?CarbonImmutable, in the calendar's timezone $hours->forDate('2026-10-12')->toString(); // "08:00–12:00, 13:00–17:00" $hours->forDate('2026-10-16')->toString(); // "Closed" ``` -------------------------------- ### Make an Eloquent model an opening hours owner Source: https://github.com/roundly-consulting/opening-hours-for-laravel/blob/main/README.md Implement the OpeningHoursOwner contract and use the HasOpeningHours trait to enable opening hours functionality on a model like Clinic. ```php use Illuminate\Database\Eloquent\Model; use RoundlyConsulting\OpeningHours\Concerns\HasOpeningHours; use RoundlyConsulting\OpeningHours\Contracts\OpeningHoursOwner; final class Clinic extends Model implements OpeningHoursOwner { use HasOpeningHours; } ```