chaplean/business-days-bundle
Installation
composer require chaplean/business-days-bundle
(Note: The README mentions Chaplean\Bundle\MailerBundle, but the package is actually ChapleanBusinessDaysBundle. Verify this in composer.json.)
Register the Bundle
In config/bundles.php (Symfony 4+), add:
return [
// ...
Chaplean\BusinessDaysBundle\ChapleanBusinessDaysBundle::class => ['all' => true],
];
First Use Case
Inject the BusinessDaysCalculator service into a controller or service:
use Chaplean\BusinessDaysBundle\Calculator\BusinessDaysCalculator;
class OrderController extends Controller
{
public function __construct(private BusinessDaysCalculator $businessDays)
{
}
public function estimateDelivery(DateTimeInterface $orderDate)
{
$businessDays = $this->businessDays->calculate(
$orderDate,
new DateTime('now'),
['Sat', 'Sun'] // Non-business days
);
return $businessDays;
}
}
Basic Business Days Calculation
$calculator = $this->container->get('chaplean_business_days.calculator');
$days = $calculator->calculate(
new DateTime('2023-10-01'), // Start date
new DateTime('2023-10-10'), // End date
['Sat', 'Sun'] // Non-business days
);
Holiday Exclusions Extend the calculator to exclude holidays dynamically:
$holidays = ['2023-12-25', '2024-01-01']; // Christmas, New Year's
$days = $calculator->calculate(
$startDate,
$endDate,
['Sat', 'Sun'],
$holidays
);
Recurring Events
Use a BusinessDaysCalculatorInterface implementation to handle recurring holidays (e.g., monthly):
$calculator->addRecurringHoliday(
'2023-12-25', // Base date
'P1M' // Recurrence rule (monthly)
);
Integration with Laravel
Bind the service in AppServiceProvider:
public function register()
{
$this->app->bind('businessDays', function ($app) {
return new \Chaplean\BusinessDaysBundle\Calculator\BusinessDaysCalculator();
});
}
Command-Line Usage Create an Artisan command for batch processing:
use Chaplean\BusinessDaysBundle\Calculator\BusinessDaysCalculator;
class CalculateBusinessDaysCommand extends Command
{
protected $calculator;
public function __construct(BusinessDaysCalculator $calculator)
{
parent::__construct();
$this->calculator = $calculator;
}
protected function handle()
{
$days = $this->calculator->calculate(
new DateTime($this->argument('start')),
new DateTime($this->argument('end'))
);
$this->info("Business days: {$days}");
}
}
Bundle Registration
MailerBundle, but the package is BusinessDaysBundle. Double-check the namespace in composer.json and config/bundles.php.AppKernel.php includes the bundle in the correct environment (e.g., prod, dev).Time Zone Sensitivity
DateTime objects:
$date = new DateTime('now', new DateTimeZone('America/New_York'));
Holiday Handling
BusinessDaysCalculator or use a third-party library like spatie/holidays for dynamic holiday lists.Edge Cases
0 if $startDate and $endDate are the same. Handle this in your logic:
if ($startDate >= $endDate) {
return 0;
}
['Sat', 'Sun']) are passed correctly. Defaults may vary.Performance
carbon/carbon with custom logic.Verify Inputs
Log the $startDate, $endDate, and non-business days to ensure they match expectations:
\Log::debug('Calculating between', [
'start' => $startDate->format('Y-m-d H:i:s'),
'end' => $endDate->format('Y-m-d H:i:s'),
'nonBusinessDays' => json_encode($nonBusinessDays),
]);
Test with Known Values Use a fixed date range to validate:
$days = $calculator->calculate(
new DateTime('2023-10-02'), // Monday
new DateTime('2023-10-06') // Friday
);
// Expected: 4 business days (Mon-Fri)
Custom Calculators
Implement Chaplean\BusinessDaysBundle\Calculator\BusinessDaysCalculatorInterface to add logic (e.g., partial-day handling):
class CustomBusinessDaysCalculator implements BusinessDaysCalculatorInterface
{
public function calculate(DateTimeInterface $start, DateTimeInterface $end, array $nonBusinessDays, array $holidays = [])
{
// Custom logic here
}
}
Event Listeners Dispatch events for business day calculations (e.g., logging or notifications):
$dispatcher->addListener(
'chaplean.business_days.calculate',
function ($event) {
\Log::info('Business days calculated', $event->getData());
}
);
Configuration
Override defaults in config/packages/chaplean_business_days.yaml:
chaplean_business_days:
default_non_business_days: ['Sat', 'Sun']
time_zone: 'UTC'
How can I help you explore Laravel packages today?