1

What I am trying to do is get the date ($date_before_that_expiry) which is $time_to_expiry (6) days before $distinct_expiries (26-Oct-2017) in the format DD-MM-YYYY

However, if the returned date is is in array ($trading_holiday_array) then it should move the returned date ($date_before_that_expiry) one day before. This is to be done recursively.

Eg: if I get a date 20-Oct-2017 initially it should return me 18-Oct-2017 and not 19th as 19-Oct-2017 is also a part of ($trading_holiday_array).

Here is the code I have put down but it goes into an infinite loop:

<?php
$distinct_expiries='26-Oct-2017';
$time_to_expiry=6;
$trading_holiday_array = array('19-Oct-2017', '20-Oct-2017');

$date_before_that_expiry = date('d-M-Y', strtotime("-$time_to_expiry days", strtotime($distinct_expiries)));

while(in_array($date_before_that_expiry, $trading_holiday_array)) {
$new_lookback= -(1+$time_to_expiry)." days";
$date_before_that_expiry = date('d-M-Y', strtotime("$new_lookback", strtotime($distinct_expiries)));

}
echo $date_before_that_expiry;

?>

Please assist.

5
  • 1
    Step one: Convert the dates into DateTime objects. Always use DateTime objects internally; never use string format dates anywhere in your code except for the edges (ie the point of input, and when you display them back to the screen). Once you have your dates stored as objects, you'll be able to search, sort, etc much more easily. Commented Apr 21, 2018 at 20:48
  • my step one would be to implement only the logic with simple ints. Then transfer that to DateTime. Now you have a bunch of complicated code for an actually simple task. Commented Apr 21, 2018 at 20:50
  • Well I am not well versed with php. Could you please help with a short code snippet? Commented Apr 21, 2018 at 20:53
  • Use if instead of while and infinite loop solved. Commented Apr 21, 2018 at 21:00
  • No but it stops after one iteration when using if Commented Apr 21, 2018 at 21:04

2 Answers 2

1

Here's an implementation of your logic with simple ints, that you'd just need to transfer to DateTime.

<?php
$blocked = [24,32,33,34,35];
$distance = 2;

function getFirstAllowed($i, $blocked, $distance) {
    $target = $i-$distance;
    while(in_array($target, $blocked)) {
        $target--;
    }   
    return $target;
}

// testing:
echo getFirstAllowed(26, $blocked, $distance)."<br>"; // 23
echo getFirstAllowed(27, $blocked, $distance)."<br>"; // 25
echo getFirstAllowed(36, $blocked, $distance)."<br>"; // 31

The same transferred to DateTime:

<?php
$blocked = [
    new DateTime("2017-10-19"),
    new DateTime("2017-10-20")
];
$timeToExpiry = new DateInterval("P6D");  // read as 'Period: 6 Days'. "P1Y3M" would be one year, 3 months

function getFirstAllowed(DateTime $startdate, Array $blocked, DateInterval $timeToExpiry) {
    $target = $startdate->sub($timeToExpiry);
    $oneDayInterval = new DateInterval("P1D");
    while(in_array($target, $blocked)) {
        $target->sub($oneDayInterval);
    }   
    return $target;
}

// testing
echo getFirstAllowed(new DateTime("2017-10-25"), $blocked, $timeToExpiry)->format("Y-m-d")."<br>"; // 2017-10-18
echo getFirstAllowed(new DateTime("2017-10-26"), $blocked, $timeToExpiry)->format("Y-m-d")."<br>"; // 2017-10-18
echo getFirstAllowed(new DateTime("2017-10-31"), $blocked, $timeToExpiry)->format("Y-m-d")."<br>"; // 2017-10-25
Sign up to request clarification or add additional context in comments.

2 Comments

Great Jeff! Works brilliantly well. Thanks for the approach of using numbers instead. :)
I thinks it's important to first get the logic sorted, which is much simpler if you don't have to bother with tranformations. And then using the right classes makes it easier to read and maintain afterwards.
0

I think I got the answer after tinkering a bit:

<?php
$distinct_expiries='26-Oct-2017';
$time_to_expiry=6;
$trading_holiday_array = array('19-Oct-2017', '20-Oct-2017');

$date_before_that_expiry = date('d-M-Y', strtotime("-$time_to_expiry days", strtotime($distinct_expiries)));

while(in_array($date_before_that_expiry, $trading_holiday_array)) {
$time_to_expiry+=1;
$date_before_that_expiry = date('d-M-Y', strtotime("-$time_to_expiry days", strtotime($distinct_expiries)));
}

echo $date_before_that_expiry;
?>

I was using the same $time_to_expiry and that caused the loop to become infinite. :-P

Any further refinements is appreciated.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.