cmixin / business-time
Carbon mixin to handle business days and opening hours
Fund package maintenance!
Open Collective
Tidelift
Installs: 664 266
Dependents: 1
Suggesters: 0
Security: 0
Stars: 299
Watchers: 3
Forks: 15
Open Issues: 0
Requires
- php: >=7.1
- cmixin/business-day: ^1.16.1
- spatie/opening-hours: ^2.9 || ^3.0.0 || ^4.0.0
Requires (Dev)
- phpunit/phpunit: ^7.5.20 || ^8.5.31 || ^9.5.27
README
Carbon mixin to handle business days and opening hours
Professionally supported nesbot/carbon is now available
Install
composer require cmixin/business-time
Usage
First load the mixin in some global bootstrap place of your app:
<?php use Carbon\Carbon; use Cmixin\BusinessTime; BusinessTime::enable(Carbon::class); // Or if you use Laravel: // BusinessTime::enable('Illuminate\Support\Carbon'); // And you can enable multiple classes at once: BusinessTime::enable([ Carbon::class, CarbonImmutable::class, ]); // As a second argument you can set default opening hours: BusinessTime::enable(Carbon::class, [ 'monday' => ['09:00-12:00', '13:00-18:00'], 'tuesday' => ['09:00-12:00', '13:00-18:00'], 'wednesday' => ['09:00-12:00'], 'thursday' => ['09:00-12:00', '13:00-18:00'], 'friday' => ['09:00-12:00', '13:00-20:00'], 'saturday' => ['09:00-12:00', '13:00-16:00'], 'sunday' => [], 'exceptions' => [ '2016-11-11' => ['09:00-12:00'], '2016-12-25' => [], '01-01' => [], // Recurring on each 1st of january '12-25' => ['09:00-12:00'], // Recurring on each 25th of december ], // You can use the holidays provided by BusinessDay // and mark them as fully closed days using 'holidaysAreClosed' 'holidaysAreClosed' => true, // Note that exceptions will still have the precedence over // the holidaysAreClosed option. 'holidays' => [ 'region' => 'us-ny', // Load the official list of holidays from USA - New York 'with' => [ 'labor-day' => null, // Remove the Labor Day (so the business is open) 'company-special-holiday' => '04-07', // Add some custom holiday of your company ], ], ]);
Business days methods are now available on any Carbon instance used anywhere later.
Features
By enabling BusinessTime
you automatically benefit on every holidays features of BusinessDay
,
see cmixin/business-day
As soon as you set opening hours (using the second parameter of BusinessTime::enable()
,
Carbon::setOpeningHours([...])
or $carbonDate->setOpeningHours([...])
), you'll be able to retrieve opening hours
on any Carbon instance or statically ($carbonDate->getOpeningHours()
or Carbon::getOpeningHours()
) as an
instance of OpeningHours
(spatie/opening-hours
),
see spatie/opening-hours for complete list of features of this class.
Then with opening hours, you'll get the following methods directly available on Carbon instances:
Holidays
By default, holidays has no particular opening hours, it will use the opening hours of the current day of week, but
you can use the 'holidaysAreClosed' => true
option to close the business on every holiday that is not specified
otherwise in the 'exceptions'
option. Else you can use a custom exception handler to link holidays or any dynamic
calculation as below:
BusinessTime::enable(Carbon::class, [ 'monday' => ['09:00-12:00', '13:00-18:00'], 'tuesday' => ['09:00-12:00', '13:00-18:00'], 'wednesday' => ['09:00-12:00'], 'thursday' => ['09:00-12:00', '13:00-18:00'], 'friday' => ['09:00-12:00', '13:00-20:00'], 'saturday' => ['09:00-12:00', '13:00-16:00'], 'sunday' => [], 'exceptions' => [ function (Carbon $date) { if ($date->isHoliday()) { // Or use ->isObservedHoliday() and set observed holidays: // https://github.com/kylekatarnls/business-day#setobservedholidayszone switch ($date->getHolidayId()) { // If the ID "christmas" exists in the selected holidays region and matches the current date: case 'christmas': return ['10:00-12:00']; default: return []; // All other holidays are closed all day long // Here you can also pass context data: return [ 'hours' => [], 'data' => [ 'reason' => 'Today is ' . $date->getHolidayName(), ], ]; } } // Else, typical day => use days of week settings }, ], ]); Carbon::setHolidaysRegion('us-national'); Carbon::parse('2018-12-25 11:00')->isOpen(); // true matches custom opening hours of Christmas Carbon::parse('2018-12-25 13:00')->isOpen(); // false Carbon::parse('2019-01-01 11:00')->isOpen(); // false closed all day long Carbon::parse('2019-01-02 11:00')->isOpen(); // true not an holiday in us-national region, so it's open as any common wednesday
Multiple business-hours
To work with multiple schedules or to use all the features without loading globally the mixin into Carbon
,
you can create Schedule
instances:
use Carbon\CarbonImmutable; use BusinessTime\Schedule; $us = Schedule::create([ 'monday' => ['09:00-12:00', '13:00-18:00'], 'tuesday' => ['09:00-12:00', '13:00-18:00'], 'wednesday' => ['09:00-12:00'], 'thursday' => ['09:00-12:00', '13:00-18:00'], 'friday' => ['09:00-12:00', '13:00-20:00'], 'holidaysAreClosed' => true, 'holidays' => [ 'region' => 'us-ny', 'with' => [ 'labor-day' => null, 'company-special-holiday' => '04-07', ], ], ]); $fr = Schedule::create([ 'monday' => ['08:00-12:00', '13:00-17:00'], 'tuesday' => ['08:00-12:00', '13:00-17:00'], 'wednesday' => ['08:00-12:00'], 'thursday' => ['08:00-12:00', '13:00-17:00'], 'friday' => ['08:00-12:00', '13:00-17:00'], 'holidaysAreClosed' => true, 'holidays' => [ 'region' => 'fr-national', 'with' => [ 'company-special-holiday' => '24/8', ], ], ]); $d = CarbonImmutable::parse('2022-10-21 06:40:00'); echo $us->subOpenHours($d, 1)->format('Y-m-d H:i:s'); // 2022-10-20 17:00:00 echo $fr->subOpenHours($d, 1)->format('Y-m-d H:i:s'); // 2022-10-20 16:00:00 $d = CarbonImmutable::parse('2022-10-20 17:30:00'); var_dump($us->isOpen($d)); // true var_dump($fr->isOpen($d)); // false
isOpenOn
Allows to know if the business is usually on open on a given day.
Carbon::isOpenOn('monday') // Returns true if there is at least 1 open range of // hours set for Monday (in the regular schedule) // Carbon::MONDAY would also works $date->isOpenOn('monday') // Same as above but using local config of $date Carbon::isOpenOn('2020-09-03') // Returns true if there is at least 1 open range of // hours set for the date 2020-09-03 (considering both // the regular schedule and the exceptions)
isClosedOn
Opposite of isOpenOn
Carbon::isClosedOn('monday') Carbon::isClosedOn('2020-09-03') $date->isClosedOn('monday')
isOpen
Allows to know if the business is usually on open at a given moment.
Carbon::isOpen() // returns true if the business is now open $carbonDate->isOpen() // returns true if the business is open at the current date and time if (Carbon::isOpen()) { $closingTime = Carbon::nextClose()->isoFormat('LT'); echo "It's now open and until $closingTime."; }
isClosed
Opposite of isOpen
Carbon::isClosed() // returns true if the business is now closed $carbonDate->isClosed() // returns true if the business is closed at the current date and time if (Carbon::isClosed()) { $openingTime = Carbon::nextClose()->calendar(); echo "It's now closed and will re-open $openingTime."; }
nextOpen
Go to next open-business time.
Carbon::nextOpen() // go to next open time from now $carbonDate->nextOpen() // go to next open time from $carbonDate
nextClose
Go to next closed-business time.
Carbon::nextClose() // go to next close time from now $carbonDate->nextClose() // go to next close time from $carbonDate
previousOpen
Go to previous open-business time.
Carbon::previousOpen() // go to previous open time from now $carbonDate->previousOpen() // go to previous open time from $carbonDate
previousClose
Go to previous closed-business time.
Carbon::previousClose() // go to previous close time from now $carbonDate->previousClose() // go to previous close time from $carbonDate
addOpenTime
Add the given interval of time taking only into account open ranges of hours.
For instance, if the current day has ["09:00-12:00", "13:30-17:00"]
open range
of hours, adding 2 open hours when it's 11am will actually add 3 hours and 30
minutes (step over the midday break: an hour and a half) and so set the time to
14:30.
Carbon::addOpenTime('2 hours and 30 minutes') // add 2 hours and 30 minutes to now $carbonDate->addOpenTime('2 hours and 30 minutes') // add 2 hours and 30 minutes to $carbonDate // Can be used with the same interval definitions than add/sub methods of Carbon $carbonDate->addOpenTime(235, 'seconds') $carbonDate->addOpenTime(new DateInterval('PT1H23M45S')) $carbonDate->addOpenTime(CarbonInterval::hours(3)->minutes(20)) $carbonDate->addOpenTime('2 hours and 30 minutes', BusinessTime::HOLIDAYS_ARE_CLOSED) // add 2 hours and 30 minutes considering holidays as closed (equivalent than using 'holidaysAreClosed' => true option)
addOpenHours
Add the given number of hours taking only into account open ranges of hours.
Carbon::addOpenHours(3) // add 3 open hours to now $carbonDate->addOpenHours(3) // add 3 open hours to $carbonDate $carbonDate->addOpenHours(3, BusinessTime::HOLIDAYS_ARE_CLOSED) // add 3 open hours considering holidays as closed (equivalent than using 'holidaysAreClosed' => true option)
addOpenMinutes
Add the given number of minutes taking only into account open ranges of hours.
Carbon::addOpenMinutes(3) // add 3 open minutes to now $carbonDate->addOpenMinutes(3) // add 3 open minutes to $carbonDate $carbonDate->addOpenMinutes(3, BusinessTime::HOLIDAYS_ARE_CLOSED) // add 3 open minutes considering holidays as closed (equivalent than using 'holidaysAreClosed' => true option)
addClosedTime
Add the given interval of time taking only into account closed ranges of hours.
Carbon::addClosedTime('2 hours and 30 minutes') // add 2 hours and 30 minutes to now $carbonDate->addClosedTime('2 hours and 30 minutes') // add 2 hours and 30 minutes to $carbonDate // Can be used with the same interval definitions than add/sub methods of Carbon $carbonDate->addClosedTime(235, 'seconds') $carbonDate->addClosedTime(new DateInterval('PT1H23M45S')) $carbonDate->addClosedTime(CarbonInterval::hours(3)->minutes(20)) $carbonDate->addClosedTime('2 hours and 30 minutes', BusinessTime::HOLIDAYS_ARE_CLOSED) // add 2 hours and 30 minutes considering holidays as closed (equivalent than using 'holidaysAreClosed' => true option)
addClosedHours
Add the given number of hours taking only into account closed ranges of hours.
Carbon::addClosedHours(3) // add 3 closed hours to now $carbonDate->addClosedHours(3) // add 3 closed hours to $carbonDate $carbonDate->addClosedHours(3, BusinessTime::HOLIDAYS_ARE_CLOSED) // add 3 closed hours considering holidays as closed (equivalent than using 'holidaysAreClosed' => true option)
addClosedMinutes
Add the given number of minutes taking only into account closed ranges of hours.
Carbon::addClosedMinutes(3) // add 3 closed minutes to now $carbonDate->addClosedMinutes(3) // add 3 closed minutes to $carbonDate $carbonDate->addClosedMinutes(3, BusinessTime::HOLIDAYS_ARE_CLOSED) // add 3 closed minutes considering holidays as closed (equivalent than using 'holidaysAreClosed' => true option)
subOpenTime
Subtract the given interval of time taking only into account open ranges of hours.
Carbon::subOpenTime('2 hours and 30 minutes') // subtract 2 hours and 30 minutes to now $carbonDate->subOpenTime('2 hours and 30 minutes') // subtract 2 hours and 30 minutes to $carbonDate // Can be used with the same interval definitions than add/sub methods of Carbon $carbonDate->subOpenTime(235, 'seconds') $carbonDate->subOpenTime(new DateInterval('PT1H23M45S')) $carbonDate->subOpenTime(CarbonInterval::hours(3)->minutes(20)) $carbonDate->subOpenTime('2 hours and 30 minutes', BusinessTime::HOLIDAYS_ARE_CLOSED) // subtract 2 hours and 30 minutes considering holidays as closed (equivalent than using 'holidaysAreClosed' => true option)
subOpenHours
Subtract the given number of hours taking only into account open ranges of hours.
Carbon::subOpenHours(3) // subtract 3 open hours to now $carbonDate->subOpenHours(3) // subtract 3 open hours to $carbonDate $carbonDate->subOpenHours(3, BusinessTime::HOLIDAYS_ARE_CLOSED) // subtract 3 open hours considering holidays as closed (equivalent than using 'holidaysAreClosed' => true option)
subOpenMinutes
Subtract the given number of minutes taking only into account open ranges of hours.
Carbon::subOpenMinutes(3) // subtract 3 open minutes to now $carbonDate->subOpenMinutes(3) // subtract 3 open minutes to $carbonDate $carbonDate->subOpenMinutes(3, BusinessTime::HOLIDAYS_ARE_CLOSED) // subtract 3 open minutes considering holidays as closed (equivalent than using 'holidaysAreClosed' => true option)
subClosedTime
Subtract the given interval of time taking only into account closed ranges of hours.
Carbon::subClosedTime('2 hours and 30 minutes') // subtract 2 hours and 30 minutes to now $carbonDate->subClosedTime('2 hours and 30 minutes') // subtract 2 hours and 30 minutes to $carbonDate // Can be used with the same interval definitions than add/sub methods of Carbon $carbonDate->subClosedTime(235, 'seconds') $carbonDate->subClosedTime(new DateInterval('PT1H23M45S')) $carbonDate->subClosedTime(CarbonInterval::hours(3)->minutes(20)) $carbonDate->subClosedTime('2 hours and 30 minutes', BusinessTime::HOLIDAYS_ARE_CLOSED) // subtract 2 hours and 30 minutes considering holidays as closed (equivalent than using 'holidaysAreClosed' => true option)
subClosedHours
Subtract the given number of hours taking only into account closed ranges of hours.
Carbon::subClosedHours(3) // subtract 3 closed hours to now $carbonDate->subClosedHours(3) // subtract 3 closed hours to $carbonDate $carbonDate->subClosedHours(3, BusinessTime::HOLIDAYS_ARE_CLOSED) // subtract 3 closed hours considering holidays as closed (equivalent than using 'holidaysAreClosed' => true option)
subClosedMinutes
Subtract the given number of minutes taking only into account closed ranges of hours.
Carbon::subClosedMinutes(3) // subtract 3 closed minutes to now $carbonDate->subClosedMinutes(3) // subtract 3 closed minutes to $carbonDate $carbonDate->subClosedMinutes(3, BusinessTime::HOLIDAYS_ARE_CLOSED) // subtract 3 closed minutes considering holidays as closed (equivalent than using 'holidaysAreClosed' => true option)
getCurrentDayOpeningHours
Returns the opening hours current day settings (first matching exception or else current weekday settings).
BusinessTime::enable(Carbon::class, [ 'monday' => [ 'data' => [ 'remarks' => 'Extra evening on Monday', ], 'hours' => [ '09:00-12:00', '13:00-18:00', '19:00-20:00', ] ], // ... ]); $todayRanges = Carbon::getCurrentDayOpeningHours(); // Equivalent to Carbon::now()->getCurrentDayOpeningHours() // You can also get opening hours of any other day: Carbon::parse('2018-01-16')->getCurrentDayOpeningHours() echo '<h1>Today office open hours</h1>'; $data = $todayRanges->getData(); if (is_array($data) && isset($data['remarks'])) { echo '<p><em>' . $data['remarks'] . '</em></p>'; } // $todayRanges is iterable on every time range of the day. foreach ($todayRanges as $range) { // TimeRange object have start, end and data properties but can also be implicitly converted as strings: echo '<p><time>' . $range . '</time></p>'; } // $todayRanges can also be directly dumped as string echo '<p>' . $todayRanges . '</p>';
isBusinessOpen / isOpenExcludingHolidays
Equivalent to isOpen
when 'holidaysAreClosed'
is set to true
.
Allows to know if the business is usually on open at a given moment and not an holidays. But you also can handle holidays with a dedicated exception for a finest setting. See Holidays section
Carbon::setHolidaysRegion('us-national'); Carbon::isBusinessOpen() // returns true if the business is now open and not an holiday $carbonDate->isBusinessOpen() // returns true if the business is open and not an holiday at the current date and time
isBusinessClosed / isClosedIncludingHolidays
Equivalent to isClosed
when 'holidaysAreClosed'
is set to true
.
Opposite of isOpenExcludingHolidays
Carbon::setHolidaysRegion('us-national'); Carbon::isBusinessClosed() // returns true if the business is now closed or an holiday $carbonDate->isBusinessClosed() // returns true if the business is closed or an holiday at the current date and time
nextBusinessOpen / nextOpenExcludingHolidays
Equivalent to nextOpen
when 'holidaysAreClosed'
is set to true
.
Go to next open time (considering all holidays as closed time). But prefer to handle holidays with a dedicated exception for a finest setting. See Holidays section
Carbon::setHolidaysRegion('us-national'); echo Carbon::nextBusinessOpen(); echo $carbonDate->nextBusinessOpen();
nextBusinessClose / nextCloseIncludingHolidays
Equivalent to nextClose
when 'holidaysAreClosed'
is set to true
.
Go to next closed time (considering all holidays as closed time). But prefer to handle holidays with a dedicated exception for a finest setting. See Holidays section
Carbon::setHolidaysRegion('us-national'); echo Carbon::nextBusinessClose(); echo $carbonDate->nextBusinessClose();
previousBusinessOpen / previousOpenExcludingHolidays
Equivalent to previousOpen
when 'holidaysAreClosed'
is set to true
.
Go to previous open time (considering all holidays as closed time). But prefer to handle holidays with a dedicated exception for a finest setting. See Holidays section
Carbon::setHolidaysRegion('us-national'); echo Carbon::previousBusinessOpen(); echo $carbonDate->previousBusinessOpen();
previousBusinessClose / previousCloseIncludingHolidays
Equivalent to previousClose
when 'holidaysAreClosed'
is set to true
.
Go to previous closed time (considering all holidays as closed time). But prefer to handle holidays with a dedicated exception for a finest setting. See Holidays section
Carbon::setHolidaysRegion('us-national'); echo Carbon::previousBusinessClose(); echo $carbonDate->previousBusinessClose();
currentOr*
Methods starting with currentOr
are followed by:
- a time-direction:
Next
/Previous
- optionally
Business
(meaning holidays are automatically considered as closed no matter the'holidaysAreClosed'
is true or false) - a state
Open
/Close
All currentOr*
methods return the current date-time if it's in the state
(see above), else they return the first date-time (next or previous according
to the given time-direction) where a state change to be the chosen state
(open / close).
Note: BusinessOpen
can also be written explicitly as OpenExcludingHolidays
and BusinessClose
as CloseIncludingHolidays
.
openOr*
Methods starting with openOr
are followed by:
- a time-direction:
Next
/Previous
- optionally
Business
(meaning holidays are automatically considered as closed no matter the'holidaysAreClosed'
is true or false) Close
(for open-or-next/previous-open, see currentOr*)
All openOr*
methods return the current date-time if it's open, else
they return the first date-time (next or previous according
to the given time-direction) the business close.
Note: BusinessClose
can also be written explicitly as CloseIncludingHolidays
.
closedOr*
Methods starting with closedOr
are followed by:
- a time-direction:
Next
/Previous
- optionally
Business
(meaning holidays are automatically considered as closed no matter the'holidaysAreClosed'
is true or false) Open
(for closed-or-next/previous-closed, see currentOr*)
All closedOr*
methods return the current date-time if it's closed, else
they return the first date-time (next or previous according
to the given time-direction) the business open.
Note: BusinessOpen
can also be written explicitly as OpenExcludingHolidays
.
diffAsBusinessInterval
Return open/closed interval of time between 2 dates/times.
$start = '2021-04-05 21:00'; $end = '2021-04-05 10:00:00'; // can be date instance, a string representation or a timestamp $options = 0; $interval = Carbon::parse($start)->diffAsBusinessInterval($end, $options);
The returned $interval
is an instance of CarbonInterval
. See https://carbon.nesbot.com/docs/#api-interval
Options are piped flags among:
BusinessTime::CLOSED_TIME
: return the interval of for closed time, return open time elseBusinessTime::RELATIVE_DIFF
: return negative value if start is before endBusinessTime::HOLIDAYS_ARE_CLOSED
: automatically consider holidays as closedBusinessTime::USE_DAYLIGHT_SAVING_TIME
: use DST native PHP diff result instead of real time (timestamp)
Examples:
Carbon::parse($start)->diffAsBusinessInterval($end, BusinessTime::CLOSED_TIME | BusinessTime::HOLIDAYS_ARE_CLOSED | BusinessTime::RELATIVE_DIFF); // - return relative total closed time between $start and $end // - considering holidays as closed // - it will be negative if $start < $end
diffInBusinessUnit
Return open/closed time in the given unit between 2 dates/times.
Carbon::parse('2021-04-05 10:00')->diffInBusinessUnit('hour', '2021-04-05 21:00:00', $options)
The first parameter is the unit singular or plural, in any case. The 2 other parameters are
the same as in diffAsBusinessInterval
diffInBusinessHours
Return open/closed number of hours (as a floating number) in the given unit between 2 dates/times.
Carbon::parse('2021-04-05 07:00')->diffInBusinessHours('2021-04-05 10:30', $options) // return 2.5 if business is open between 8:00 and 12:00
The 2 parameters are
the same as in diffAsBusinessInterval
diffInBusinessMinutes
Return open/closed number of minutes (as a floating number) in the given unit between 2 dates/times.
Carbon::parse('2021-04-05 07:00')->diffInBusinessMinutes('2021-04-05 10:30', $options)
The 2 parameters are
the same as in diffAsBusinessInterval
diffInBusinessSeconds
Return open/closed number of seconds (as a floating number) in the given unit between 2 dates/times.
Carbon::parse('2021-04-05 07:00')->diffInBusinessSeconds('2021-04-05 10:30', $options)
The 2 parameters are
the same as in diffAsBusinessInterval
getCurrentOpenTimeRanges
Get list of ranges that contain the current date-time.
foreach (Carbon::getCurrentOpenTimeRanges() as $timeRange) { echo 'From: '.$timeRange->start().' to '.$timeRange->end()."\n"; } foreach ($carbonDate->getCurrentOpenTimeRanges() as $timeRange) { echo 'From: '.$timeRange->start().' to '.$timeRange->end()."\n"; }
getCurrentOpenTimeRange
Get the first range that contain the current date-time.
$timeRange = Carbon::getCurrentOpenTimeRange(); if ($timeRange) { echo 'From: '.$timeRange->start().' to '.$timeRange->end()."\n"; } $timeRange = $carbonDate->getCurrentOpenTimeRange(); if ($timeRange) { echo 'From: '.$timeRange->start().' to '.$timeRange->end()."\n"; }
getCurrentOpenTimePeriod
Get the first range that contain the current date-time as a CarbonPeriod
.
While getCurrentOpenTimeRange()
return a TimeRange
instance which only handle the time part, getCurrentOpenTimePeriod()
return
a CarbonPeriod
instance so you get whole date and time of the start and end.
This is mostly useful when having ranges overflowing midnight:
BusinessTime::enable(Carbon::class, [ 'overflow' => true, 'monday' => ['22:00-03:00'], ]); $timeRange = Carbon::getCurrentOpenTimePeriod(); // with current date and time $timeRange = Carbon::parse('Monday 23:34')->getCurrentOpenTimePeriod(); echo $timeRange->getStartDate()->format('D G\h'); // Mon 22h echo $timeRange->getEndDate()->format('D G\h'); // Tue 3h
getCurrentOpenTimeRangeStart
Get the start of the current open time range (if open, holidays ignored).
$start = Carbon::getCurrentOpenTimeRangeStart(); if ($start) { echo 'Open since '.$start->format('l H:i')."\n"; } else { echo "Closed\n"; } $start = $carbonDate->getCurrentOpenTimeRangeStart(); if ($start) { echo 'Open since '.$start->format('l H:i')."\n"; } else { echo "Closed\n"; }
getCurrentOpenTimeRangeEnd
Get the end of the current open time range (if open, holidays ignored).
$end = Carbon::getCurrentOpenTimeRangeEnd(); if ($end) { echo 'Will close at '.$start->format('l H:i')."\n"; } else { echo "Closed\n"; } $end = $carbonDate->getCurrentOpenTimeRangeEnd(); if ($end) { echo 'Will close at '.$start->format('l H:i')."\n"; } else { echo "Closed\n"; }
getCurrentBusinessTimeRangeStart
Get the start of the current open time range (if open and not holiday).
$start = Carbon::getCurrentBusinessTimeRangeStart(); if ($start) { echo 'Open since '.$start->format('l H:i')."\n"; } else { echo "Closed\n"; } $start = $carbonDate->getCurrentBusinessTimeRangeStart(); if ($start) { echo 'Open since '.$start->format('l H:i')."\n"; } else { echo "Closed\n"; }
getCurrentBusinessTimeRangeEnd
Get the end of the current open time range (if open and not holiday).
$end = Carbon::getCurrentBusinessTimeRangeEnd(); if ($end) { echo 'Will close at '.$start->format('l H:i')."\n"; } else { echo "Closed\n"; } $end = $carbonDate->getCurrentBusinessTimeRangeEnd(); if ($end) { echo 'Will close at '.$start->format('l H:i')."\n"; } else { echo "Closed\n"; }
Laravel
To enable business-time globally in Laravel, set default openning hours and holidays settings in the config file config/carbon.php (create this file if it does not exist yet):
<?php return [ 'opening-hours' => [ 'monday' => ['09:00-12:00', '13:00-18:00'], 'tuesday' => ['09:00-12:00', '13:00-18:00'], 'wednesday' => ['09:00-12:00'], 'thursday' => ['09:00-12:00', '13:00-18:00'], 'friday' => ['09:00-12:00', '13:00-20:00'], 'saturday' => ['09:00-12:00', '13:00-16:00'], 'sunday' => [], 'exceptions' => [ '2016-11-11' => ['09:00-12:00'], '2016-12-25' => [], '01-01' => [], // Recurring on each 1st of january '12-25' => ['09:00-12:00'], // Recurring on each 25th of december ], ], 'holidaysAreClosed' => true, 'holidays' => [ 'region' => 'us', 'with' => [ 'boss-birthday' => '09-26', 'last-monday' => '= last Monday of October', ], ], ];
If you use Laravel but don't plan to use this global config to enable business-time, you may remove it from auto-discovery using:
"extra": { "laravel": { "dont-discover": [ "cmixin/business-day", "cmixin/business-time" ] } },
Note about timezones
When you set an holidays region, it does not change the timezone, so if January 1st is an holiday,
->isHoliday()
returns true
from Carbon::parse('2010-01-01 00:00:00.000000)
to
Carbon::parse('2010-01-01 23:59:59.999999)
no matter the timezone you set for those Carbon
instance.
If you want to know if it's holiday or business day in somewhere else in the world, you have to convert it:
Carbon::parse('2010-01-01 02:30', 'Europe/Paris')->setTimezone('America/Toronto')->isHoliday() // false Carbon::parse('2010-01-01 12:30', 'Europe/Paris')->setTimezone('America/Toronto')->isHoliday() // true
The same goes for opening hours, let's say you want to know if you call center based in Toronto is available from Tokyo at a given hour (Tokyo timezone), you would get something like:
// Opening hours in Toronto BusinessTime::enable(Carbon::class, [ 'monday' => ['08:00-20:00'], 'tuesday' => ['08:00-20:00'], 'wednesday' => ['08:00-20:00'], 'thursday' => ['08:00-20:00'], ]); // Can I call the hotline if it's Tuesday 19:30 in Tokyo? > No Carbon::parse('2019-03-05 20:30', 'Asia/Tokyo')->setTimezone('America/Toronto')->isOpen() // false // Can I call the hotline if it's Tuesday 22:30 in Tokyo? > Yes Carbon::parse('2019-03-05 22:30', 'Asia/Tokyo')->setTimezone('America/Toronto')->isOpen() // true