A bit similar to this one, yet different.
I need to generate two random dates:
$startDate
and $endDate
$endDate
$startHour
and $endHour
.I am doing this like that:
$createDate = new DateTime();
$updateDate = new DateTime();
$createDate
->setTimestamp(rand($startDate, $endDate))
->setTime(rand($startHour, $endHour), rand(0, 59), rand(0, 59));
$updateDate
->setTimestamp(rand($createDate->getTimestamp(), $endDate))
->setTime(rand($startHour, $endHour), rand(0, 59), rand(0, 59));
How to modify the above code to assure that both createDate
and updateDate
does not fall on Sunday?
As you can figure out from the above code, the $startDate
and $endDate
are integers and contains timestamps. The $startHour
and $endHour
are also integers, but contains pure hour numeral only.
How to modify the above code to assure that both createDate and updateDate does not fall on Sunday?
I modify your code to this:
$createDate = new DateTime();
$updateDate = new DateTime();
do {
$createDate
->setTimestamp(rand($startDate, $endDate))
->setTime(rand($startHour, $endHour), rand(0, 59), rand(0, 59));
} while ($createDate->format('N') == 7); // Repeat until createDate is not a Sunday
do {
$updateDate
->setTimestamp(rand($createDate->getTimestamp(), $endDate))
->setTime(rand($startHour, $endHour), rand(0, 59), rand(0, 59));
} while ($updateDate->format('N') == 7); // Repeat until updateDate is not a Sunday
Here, I used do...while
loop to keep generating a random date until the generated date is not a Sunday. The format('N')
is used to returns the day of the week as an integer, and 7
represents Sunday. The loop will continue until format('N')
does not return 7
, ensuring that the generated date is not a Sunday*.
*Note that this may be inefficient if the range of dates between $startDate
and $endDate
includes many Sundays, as it may take several iterations to find a date that is not a Sunday. In such, you may want to consider generating a list of all weekdays within the date range and then randomly selecting from that list, as answered by @waterloomatt here.
Generally "random" + "loop" = "infinite loop, or at least takes forever sometimes"
Add counter for a maximum number of attempts to prevent the loop from running indefinitely.
$createDate = new DateTime();
$updateDate = new DateTime();
$maxAttempts = 1000; // Maximum number of attempts to generate a non-Sunday date
$attempts = 0; // Counter for the number of attempts
do {
$createDate
->setTimestamp(rand($startDate, $endDate))
->setTime(rand($startHour, $endHour), rand(0, 59), rand(0, 59));
$attempts++;
} while ($createDate->format('N') == 7 && $attempts < $maxAttempts); // Repeat until createDate is not a Sunday
$attempts = 0; // Reset the counter for the next date
do {
$updateDate
->setTimestamp(rand($createDate->getTimestamp(), $endDate))
->setTime(rand($startHour, $endHour), rand(0, 59), rand(0, 59));
$attempts++;
} while ($updateDate->format('N') == 7 && $attempts < $maxAttempts); // Repeat until updateDate is not a Sunday
*The above may still has a possibility of infinite loop if the range of possible dates only includes Sundays and the maximum number of attempts is reached, so you could add additional logic to adjust the range of possible dates or handle the case where no non-Sunday dates are available.