Reputation: 2092
please, really need help with this problem.
I have array of offerDays - $offerDays = array(1,6);
(mean Monday, and Saturday);
For example, input date is Wednesday 2014/09/03. Next available date for offers is Saturday 2014/09/06
Question: How I can in php determine nearest next day? Something like
$offerDays = array(1,6);
$inputDate = '2014/09/03'; // filled date, not actual date
$offerDate = findDate($inputDate, $offerDays); // returns 2014/09/06
function findDate($inputDate, $offerDays) {
return 'nearest next date to $inputDate defined by $offerDays';
}
Upvotes: 1
Views: 1326
Reputation: 11
$currentDate = date('Y-m-d');
$frequencyDays = [2, 4, 5];
function nextNearestDate($currentDate, $frequencyDays) {
$weekDay = date('w', strtotime($currentDate));
$min = 10; // Some random number>7
foreach ($frequencyDays as $day) {
$dif = $day - $weekDay;
if ($dif == 0) {
$min = $dif;
break;
}else if ($dif > 0) {
$positiveDay[] = $dif;
}else if ($dif < 0) {
$negativeDay[] = $dif;
}
}
if ($min != 0) {
if (isset($positiveDay) && count($positiveDay)) {
$min = min($positiveDay);
} else {
$min = min($negativeDay);
$min = 7 + $min;
}
}
return $newDay = date('Y-m-d', strtotime('+' . $min . ' days', strtotime($currentDate)));
}
Upvotes: 1
Reputation: 48284
<?php
/**
* Return the next date that falls on one of the specified weekdays.
*
* @param DateTimeInterface $inputDate The search begins on the day after this
* @param array $weekdays An array of permitted weekdays
* represented by an integer (0=Sunday)
*
* @return DateTimeInterface|null The first date that meets the criteria
*/
function findDate(DateTimeInterface $inputDate, array $weekdays)
{
$weekdays = array_flip($weekdays);
foreach (new DatePeriod($inputDate, new DateInterval('P1D'), 7, DatePeriod::EXCLUDE_START_DATE) as $possibleDate)
{
if (isset($weekdays[$possibleDate->format('w')]) === true)
{
return $possibleDate;
}
}
}
// Example:
$weekdays = [1, 6];
$inputDate = '2014/09/03';
$offerDate = findDate(new DateTimeImmutable($inputDate), $weekdays);
echo $offerDate->format('Y-m-d'), "\n";
If you want to address this by building a slightly more abstract foundation, it may look like:
<?php
function WeekDayIterator(DateTimeInterface $inputDate, array $weekdays)
{
$weekdays = array_intersect($weekdays, range(0,6));
if (!$weekdays)
{
return;
}
$possibleDate = new DateTimeImmutable('@' . $inputDate->getTimeStamp());
$oneDay = new DateInterval('P1D');
$weekdays = array_flip($weekdays);
while (true)
{
$possibleDate = $possibleDate->add($oneDay);
if (isset($weekdays[$possibleDate->format('w')]) === true)
{
yield $possibleDate;
}
}
}
function findDate(DateTimeInterface $inputDate, array $weekdays)
{
return WeekDayIterator($inputDate, $weekdays)->current();
}
// Example:
$weekdays = [1, 6];
$inputDate = '2014/09/03';
$offerDate = findDate(new DateTimeImmutable($inputDate), $weekdays);
echo $offerDate->format('Y-m-d'), "\n";
foreach (new LimitIterator(WeekDayIterator(new DateTimeImmutable($inputDate), $weekdays), 0, 10) as $date)
{
echo $date->format('Y-m-d (w)'), "\n";
}
This longer version gives you an iterator that will infinitely loop over all valid dates. The findDate
method now just becomes a convenience method to hide away the implementation details.
But the advantage here is that you can now solve similar problems without having to write more plumbing. For example, you can compute the next 10 dates with a LimitIterator
. (Maybe you want to provide a drop down of available dates, etc.)
This second version is heavily dependent on 5.5, but the first version is not (if you replace the DateTimeImmutable
with DateTime
).
Upvotes: 0
Reputation: 3741
Here you can have a variable array for the offerdays.
$offerDays = array(1,6);
$inputDate = '2014/09/04'; // filled date, not actual date
$offerDate = findDate($inputDate, $offerDays);
function findDate($inputDate, $offerDays) {
$date = DateTime::createFromFormat('Y/m/d', $inputDate);
$num = $date->format('w');
$min = 10; //initialize minimum days
foreach($offerDays as $o){ //loop through all the offerdays to find the minimum difference
$dif = $o - $num;
if($dif>0 && $dif < $min){
$min = $dif ;
}
}
// if minimum days is not changed then get the first offerday from next week
if($min == 10){
$min = 6 - $num + min($offerDays);
}
//add the days till next offerday
$add = new DateInterval('P'.$min.'D');
$nextOfferDay = $date->add($add)->format('Y/m/d');
return $nextOfferDay;
}
Upvotes: 1
Reputation: 3663
$date_str="2014-09-03";
if(date('l' , $date_str) != 'Saturday')
{
//Your Code Here
}
Upvotes: 0