1

I've been working on this code for a while and obviously, well... my desk has suffered some head assaults.
I'm building a training calendar and after determining a start day (startDate) I want to find the date in X days (strNbrDays) from the start date.

The end date (endDate) needs to be a weekday. Also, I have a DB with specific non-training days (ntds) that must not be included in the X days.

So, I've build a query to build an array (ntds[]) of non-training days. That works fine.

The code building the array is:

$ntds = [];
$sql = mysqli_query($mysqli,"SELECT * FROM NTDs WHERE bNITD = 0 ORDER BY dDateStart");
    while ($row = mysqli_fetch_array($sql)) {
        $startDate = $row['dDateStart'];
        $endDate = $row['dDateEnd'];
        $isBlock = $row['bIsBlock'];
        $description = $row['tDesc'];
        
        if(!empty($endDate)){
            
            $iDateFrom = mktime(1, 0, 0, substr($startDate, 5, 2), substr($startDate, 8, 2), substr($startDate, 0, 4));
            $iDateTo = mktime(1, 0, 0, substr($endDate, 5, 2), substr($endDate, 8, 2), substr($endDate, 0, 4));
    
            if ($iDateTo >= $iDateFrom) {
                $ntds[] = date("Y-m-d", $iDateFrom);
    
                while ($iDateFrom<$iDateTo) {
                    $iDateFrom += 86400; // add 24 hours
                    $ntds[] = date("Y-m-d", $iDateFrom);
                }
            }
        }
        else {
            $startDateStr = mktime(1, 0, 0, substr($startDate, 5, 2), substr($startDate, 8, 2), substr($startDate, 0, 4));
            $ntds[] = date("Y-m-d", $startDateStr);
        }
    }   

This is the array :

Array ( [0] => 2022-03-12 [1] => 2022-03-13 [2] => 2022-03-14 [3] => 2022-03-15 [4] => 2022-03-16 [5] => 2022-03-17 [6] => 2022-03-18 [7] => 2022-03-19 [8] => 2022-03-20 [9] => 2022-04-07 [10] => 2022-04-15 [11] => 2022-04-18 [12] => 2022-05-23 [13] => 2022-06-03 [14] => 2022-07-01 [15] => 2022-08-01 [16] => 2022-08-06 [17] => 2022-08-07 [18] => 2022-08-08 [19] => 2022-08-09 [20] => 2022-08-10 [21] => 2022-08-11 [22] => 2022-08-12 [23] => 2022-08-13 [24] => 2022-08-14 [25] => 2022-08-15 [26] => 2022-08-16 [27] => 2022-08-17 [28] => 2022-08-18 [29] => 2022-08-19 [30] => 2022-08-20 [31] => 2022-08-21 [32] => 2022-09-05 [33] => 2022-09-15 [34] => 2022-09-16 [35] => 2022-09-23 [36] => 2022-09-30 [37] => 2022-10-10 [38] => 2022-11-11 [39] => 2022-12-14 [40] => 2022-12-15 [41] => 2022-12-16 [42] => 2022-12-17 [43] => 2022-12-18 [44] => 2022-12-19 [45] => 2022-12-20 [46] => 2022-12-21 [47] => 2022-12-22 [48] => 2022-12-23 [49] => 2022-12-24 [50] => 2022-12-25 [51] => 2022-12-26 [52] => 2022-12-27 [53] => 2022-12-28 [54] => 2022-12-29 [55] => 2022-12-30 [56] => 2022-12-31 [57] => 2023-01-01 [58] => 2023-01-02 [59] => 2023-01-03 [60] => 2023-01-04 [61] => 2023-01-05 [62] => 2023-01-06 [63] => 2023-01-07 [64] => 2023-01-08 [65] => 2023-03-11 [66] => 2023-03-12 [67] => 2023-03-13 [68] => 2023-03-14 [69] => 2023-03-15 [70] => 2023-03-16 [71] => 2023-03-17 [72] => 2023-03-18 [73] => 2023-03-19 [74] => 2023-04-07 [75] => 2023-04-10 [76] => 2023-05-18 [77] => 2023-05-22 [78] => 2023-06-30 [79] => 2023-07-13 [80] => 2023-07-14 [81] => 2023-08-05 [82] => 2023-08-06 [83] => 2023-08-07 [84] => 2023-08-08 [85] => 2023-08-09 [86] => 2023-08-10 [87] => 2023-08-11 [88] => 2023-08-12 [89] => 2023-08-13 [90] => 2023-08-14 [91] => 2023-08-15 [92] => 2023-08-16 [93] => 2023-08-17 [94] => 2023-08-18 [95] => 2023-08-19 [96] => 2023-08-20 [97] => 2023-08-07 [98] => 2023-09-04 [99] => 2023-09-14 [100] => 2023-09-15 [101] => 2023-09-22 [102] => 2023-10-02 [103] => 2023-10-09 [104] => 2023-11-11 [105] => 2023-12-13 [106] => 2023-12-14 [107] => 2023-12-15 [108] => 2023-12-17 [109] => 2023-12-18 [110] => 2023-12-19 [111] => 2023-12-20 [112] => 2023-12-21 [113] => 2023-12-22 [114] => 2023-12-23 [115] => 2023-12-24 [116] => 2023-12-25 [117] => 2023-12-26 [118] => 2023-12-27 [119] => 2023-12-28 [120] => 2023-12-29 [121] => 2023-12-30 [122] => 2023-12-31 [123] => 2024-01-01 [124] => 2024-01-02 [125] => 2024-01-03 [126] => 2024-01-04 [127] => 2024-01-05 )

Provided the following function :

function setEndDay($startDate, $strNbrDays) {   
    $countWD = 1;
    $t1 = strtotime("$startDate 00:00:00"); // start date
    $t2 = date("Y-m-d", $t1);

    while ($countWD < $strNbrDays){
        $nt1 = strtotime('+1 weekday', $t1);
        $nt2 = date("Y-m-d", $nt1);
        
        if(!in_array($nt2, $ntds)){
            $countWD++;
        }
        $t1 = $nt1;
    }
    return $nt2;
}

The code starts by setting the start date in YYYY-MM-DD format. Then executes the while loop as long as it doesn't reach the number of training days, 70 in this case. I don't need to validate the first start date because it's already been determined it wasn't in the form.

The loop adds 1 weekday to the start day and converts it to YYYY-MM-DD format, then checks to determine if the new date is in the array, and if not will add 1 to the counter thus removing one day off the training days left and then set the "start date" the value of the current new date for the loop to keep going. If that day is in the array, it won't add to the count thus "skipping" that day but still setting the "start date" the value of the current date for the loop to keep going.

At the end, the function should produce the last day in the loop.

I would then call the function with the following variables set:

$s1_startdate = 2022-08-22 and $mod1_TDs = 70

$endDate = setEndDay($s1_startdate, $mod1_TDs);

With the values of the array, endDate should be 2022-12-06, only it outputs 2022-11-25 not considering the 7 days in the non-training days array from that 70 day period.

I'm sure it's a problem somewhere in my setEndDay function, because hardcoding the content of the function in a separate page works fine. I have multiple end dates to parse in a single page so I need it to be a function.

Any help will be greatly appreciated.

  • 2
    Variable `$ntds` does not exist. You're checking against a non-existent array. – Jim Sep 02 '22 at 18:18
  • @Jim, the code that builds `$ntfs` was not added because it actually works, the result of the above array is it's result. I edited my post to add the code building the array, this code is just above the function code. I get the array when running `print_r($ntds);` – Gaétan Martin Sep 02 '22 at 19:57
  • 1
    @Jim, OMG you are so right!! the array IS non-existant in the function. I only had to attach the array $ntds to the function. `$endDate = setEndDay($s1_startdate, $mod1_TDs, $ntds);` and declare the argument in the function `function setEndDay($startDate, $strNbrDays, $ntdsArr) { `. Thank you so much! – Gaétan Martin Sep 02 '22 at 20:14
  • 1
    @Jim - You should post that as the answer. – Rohit Gupta Sep 02 '22 at 21:59

0 Answers0