1

I am struggling with the price calculation of Woocommerce Bookings for the type "days". If the price on a daterange (e.g. Monday to Wednesday or Wednesday-Saturday or Sunday-Tuesday...) is higher than on the other days.

So far I know how many days:

$days = date_diff($from, $to)->format('%d');

This question helps to get the number of single days: calculate sundays between two dates

But how do I get not only "sundays" but every daterange (e.g. from 6 to 2) with this:

$sundays = intval($days / 7) + ($from->format('N') + $days % 7 >= 7);

I guess I need to iterate through daterange and use this formula but I cannot figure out how.

achiever
  • 309
  • 1
  • 16

1 Answers1

1

You can use a completely different approach: Create a DatePeriod object and loop through the Period object and increment a variable each time you encounter the range.

The following code achieve it but only return the number of complete range:

$from='2018/09/1';
$to='2018/09/31';

$start='Sunday';
$end='Thursday';

$go=false;
$period=new DatePeriod(date_create($from),date_interval_create_from_date_string('1 days'),date_create($to));
$nRange=0;
foreach($period as $date){
    if($date->format('l')===$start){
        $go=true;

    }
    if($go&&$date->format('l')===$end){
        $go=false;
        $nRange++;
    }
}

print_r($nRange);

output :

4

It works fine for any chosen range.

However if the need is to get any valid day within the given range complete or not you can alter the previous code this way:

 $from='2018/09/17';
    $to='2018/09/31';
    $start='Sunday';
    $end='Thursday';
    $day_num=['Monday'=>1,'Tuesday'=>2,'Wednesday'=>3,'Thursday'=>4,'Friday'=>5,'Saturday'=>6,'Sunday'=>7];
    $start_num=$day_num[$start];
    $end_num=$day_num[$end];


    $period=new DatePeriod(date_create($from),date_interval_create_from_date_string('1 days'),date_create($to));
    $nRange=0;

    if($start_num===$end_num){
        $valid_range=array_values($day_num);//keep the number of each day of the week
    }
    elseif($start_num>$end_num){
        $valid_range=array_values($day_num);//keep the number of each day of the week
        while($valid_range[0]!==$start_num){//rotate the values to keep the start day first
            $pop=array_shift($valid_range);
            array_push($valid_range,$pop);

        }
        $valid_range=array_slice($valid_range,array_search($start_num,$valid_range),$start_num-$end_num);//keep only the days in the chosen range
    }else{
        $valid_range=array_values($day_num);//keep the number of each day of the week
        $valid_range=array_slice($valid_range,array_search($start_num,$valid_range),$end_num-$start_num); //keep only the days in the chosen range
    }
    $valid_range=array_flip($valid_range);//flip the array to make the search more fast
    foreach($period as $date){
        if(isset($valid_range[(int)$date->format('N')])){
            $nRange++;
        }
    }

    print_r($nRange);//output the number  of valid days 

ouput:

 6
Elementary
  • 1,443
  • 1
  • 7
  • 17
  • I will try to work with this, thank you already. But, what if one DatePeriod is only partly within that range? So start - end is 4 times within from - to, which would mean 20 days in total, but it could also be that only 18 days are within that range when the 31st is a Tuesday. – achiever Sep 10 '18 at 09:32
  • It does, but it only counts, when the complete date period is within from/to – achiever Sep 10 '18 at 14:16
  • do you need to count uncomplete period too? – Elementary Sep 10 '18 at 14:22
  • I to count every single day within the period, complete and incomplete – achiever Sep 10 '18 at 14:27
  • 1
    @achiever I edited the answer check it now and don't forget to mark your question as solved. – Elementary Sep 10 '18 at 15:52
  • This is great, just needed to add one day when from-to is a shorter range than start-end! Thank you!! – achiever Sep 10 '18 at 22:51