Reputation: 115
I can't wrap my head around this particular problem.
There is a bakery, and an office that accepts orders.
Bakery is open from Monday to Sunday, it's only closed during public holidays.
Orders can be placed from Monday to Friday unless it's a public holiday i.e. the office is open during working days.
We also need to distinguish if the user managed to order goods before or after a particular time, let's say 12:00.
A few examples:
This is what I've got so far, but the code isn't working as expected.
function freeDays()
{
return array(
'01.01' // Den obnovy českého státu, Nový rok.
, date('d.m', strtotime("-2 day", easter_date(date('Y')))) // Velký pátek
, date('d.m', strtotime("+1 day", easter_date(date('Y')))) // Velikonoční pondělí
,'01.05' // Svátek práce
,'08.05' // Den vítězství
,'05.07' // Cyrila a Metoděj
,'06.07' // Jan Hus
,'28.09' // Den české státnosti
,'28.10' // Vznik samostatného československého státu
,'17.11' // Den boje za svobodu a demokracii
,'24.12' // Štědrý den
,'25.12' // 1. svátek vánoční
,'26.12' // 2. svátek vánoční
,'31.12' // Silvestr
);
}
function bakeryClosedDays()
{
return array(
'01.01' // Den obnovy českého státu, Nový rok.
, date('d.m', strtotime("+1 day", easter_date(date('Y')))) // Velikonoční pondělí
,'08.05' // Den vítězství
,'28.09' // Den české státnosti
,'28.10' // Vznik samostatného československého státu
,'17.11' // Den boje za svobodu a demokracii
,'25.12' // 1. svátek vánoční
,'26.12' // 2. svátek vánoční
,'23.07' // TEST
// ,'24.07' // TEST
// ,'25.07' // TEST
// ,'26.07' // TEST
// ,'28.07' // TEST
);
}
function isFreeDay($timestamp)
{
return in_array(date('d.m', $timestamp), freeDays());
}
function isBakeryClosed($timestamp)
{
return in_array(date('d.m', $timestamp), bakeryClosedDays());
}
function isFriday($timestamp)
{
return date("N", $timestamp) == 5;
}
function isDeadline($timestamp)
{
return (int)date('H', $timestamp) >= 12;
}
function isWeekend($timestamp)
{
return date('N', $timestamp) >= 6;
}
function isToday($timestamp)
{
return date('d.m.Y') == date('d.m.Y', $timestamp) ;
}
function resetHours($timestamp)
{
return strtotime(date('Y-m-d', $timestamp));
}
function getOrderDay($timestamp, $postpone_order = false)
{
if ($postpone_order) {
$timestamp = strtotime("+1 day", $timestamp);
}
if (isWeekend($timestamp)) {
return getOrderDay(strtotime("next Tuesday", $timestamp));
}
if (isFriday($timestamp) && isDeadline($timestamp)) {
return getOrderDay(strtotime("next Tuesday", $timestamp));
}
if(isBakeryClosed($timestamp)) {
return getOrderDay(strtotime("+2 day", $timestamp));
}
if(isFreeDay($timestamp)) {
return getOrderDay(strtotime("+1 day", $timestamp));
}
if (isDeadline($timestamp)) {
return strtotime("+2 day", $timestamp);
}
return $timestamp;
}
$start_timestamp = strtotime('22.07.2022 10:00:00');
print_r(date('d.m.Y H:i:s', getOrderDay($start_timestamp)));
// weekday before 12 +1 day
// weekday after 12 +2 days
// red-letter day +2 days
// saturday-sunday +2 days
Upvotes: 0
Views: 51
Reputation: 115
I'd like to share my own solution, which I ended up with.
Maybe, it'll help someone in the future.
What helped me a ton was drawing all the possible combinations in graphs, then everything became much clearer and easier.
I think most of the code is self-explanatory, I tried to be as verbose with the function names and variables as possible.
function publicHolidays()
{
return array(
'01.01' // Den obnovy českého státu, Nový rok.
, date('d.m', strtotime("-2 day", easter_date(date('Y')))) // Velký pátek
, date('d.m', strtotime("+1 day", easter_date(date('Y')))) // Velikonoční pondělí
,'01.05' // Svátek práce
,'08.05' // Den vítězství
,'05.07' // Cyrila a Metoděj
,'06.07' // Jan Hus
,'28.09' // Den české státnosti
,'28.10' // Vznik samostatného československého státu
,'17.11' // Den boje za svobodu a demokracii
,'24.12' // Štědrý den
,'25.12' // 1. svátek vánoční
,'26.12' // 2. svátek vánoční
,'31.12' // Silvestr
);
}
function bakeryClosedDays()
{
return array(
'01.01' // Den obnovy českého státu, Nový rok.
, date('d.m', strtotime("+1 day", easter_date(date('Y')))) // Velikonoční pondělí
,'08.05' // Den vítězství
,'28.09' // Den české státnosti
,'28.10' // Vznik samostatného československého státu
,'17.11' // Den boje za svobodu a demokracii
,'25.12' // 1. svátek vánoční
,'26.12' // 2. svátek vánoční
// ,'19.07' // UT - TEST
// ,'20.07' // ST - TEST
,'22.07' // PA - TEST
// ,'23.07' // SO - TEST
// ,'25.07' // PO - TEST
,'26.07' // TEST
// ,'27.07' // TEST
// ,'25.07' // TEST
// ,'26.07' // TEST
// ,'28.07' // TEST
);
}
function isPublicHoliday($timestamp)
{
return in_array(date('d.m', $timestamp), publicHolidays());
}
function isBakeryClosed($timestamp)
{
return in_array(date('d.m', $timestamp), bakeryClosedDays());
}
function isAfterOrderHour($timestamp)
{
return (int)date('H', $timestamp) >= 12;
}
function isWeekend($timestamp)
{
return date('N', $timestamp) >= 6;
}
function isWorkingDay($timestamp)
{
if (isWeekend($timestamp)) {
return false;
}
if (isBakeryClosed($timestamp)) {
return false;
}
if (isPublicHoliday($timestamp)) {
return false;
}
return true;
}
function getNextWorkingDay($timestamp)
{
do {
$timestamp = strtotime('+1 day', $timestamp);
} while(!isWorkingDay($timestamp));
return $timestamp;
}
function getOrderDayTimestamp($orderTimestamp)
{
if (isAfterOrderHour($orderTimestamp) || !isWorkingDay($orderTimestamp)) {
$nextOrderOfficeProcessingTimestamp = getNextWorkingDay($orderTimestamp);
$nextOrderTimestamp = $nextOrderOfficeProcessingTimestamp;
do {
$nextOrderTimestamp = strtotime('+1 day', $nextOrderTimestamp);
} while(isBakeryClosed($nextOrderTimestamp));
return $nextOrderTimestamp;
}
$nextOrderTimestamp = $orderTimestamp;
do {
$nextOrderTimestamp = strtotime('+1 day', $nextOrderTimestamp);
} while(isBakeryClosed($nextOrderTimestamp));
return $nextOrderTimestamp;
}
$orderTimestamp = strtotime('21.07.2022 10:00:00');
printf("Chosen day | %s", date('l - d.m.Y H:i', $orderTimestamp));
echo "\n";
printf("Future order | %s", date('l - d.m.Y H:i', getOrderDayTimestamp($orderTimestamp)));
echo "\n";
echo "\n";
echo "\n";
echo "\n";
echo "\n";
echo "\n";
var_dump(isWorkingDay($orderTimestamp));;
// weekday before 12 +1 day
// weekday after 12 +2 days
// red-letter day +2 days
// saturday-sunday +2 days
Upvotes: 0