public function test_w2Psgn() { $this->assertEquals(-1, w2Psgn(-56.2)); $this->assertEquals(0, w2Psgn(0)); $this->assertEquals(1, w2Psgn(0.01)); }
public function addDuration($duration = '8', $durationType = '1') { // using a sgn function lets us easily cover // prospective and retrospective calcs at the same time // get signum of the duration $sgn = w2Psgn($duration); // make duration positive $duration = abs($duration); if ($durationType == '24') { // duration type is 24, full days, we're finished very quickly $full_working_days = $duration; } else { if ($durationType == '1') { // durationType is 1 hour // get w2P time constants $cal_day_start = (int) w2PgetConfig('cal_day_start'); $cal_day_end = (int) w2PgetConfig('cal_day_end'); $dwh = (int) w2PgetConfig('daily_working_hours'); // move to the next working day if the first day is a non-working day $sgn > 0 ? $this->next_working_day() : $this->prev_working_day(); // calculate the hours spent on the first day $firstDay = $sgn > 0 ? min($cal_day_end - $this->hour, $dwh) : min($this->hour - $cal_day_start, $dwh); /* ** Catch some possible inconsistencies: ** If we're later than cal_end_day or sooner than cal_start_day then we don't need to ** subtract any time from duration. The difference is greater than the # of daily working hours */ if ($firstDay < 0) { $firstDay = 0; } // Intraday additions are handled easily by just changing the hour value if ($duration <= $firstDay) { $sgn > 0 ? $this->setHour($this->hour + $duration) : $this->setHour($this->hour - $duration); return $this; } // the effective first day hours value $firstAdj = min($dwh, $firstDay); // subtract the first day hours from the total duration $duration -= $firstAdj; // we've already processed the first day; move by one day! $this->addDays(1 * $sgn); // make sure that we didn't move to a non-working day $sgn > 0 ? $this->next_working_day() : $this->prev_working_day(); // end of proceeding the first day // calc the remaining time and the full working days part of this residual $hoursRemaining = $duration > $dwh ? $duration % $dwh : $duration; $full_working_days = round(($duration - $hoursRemaining) / $dwh); // (proceed the full days later) // proceed the last day now // we prefer wed 16:00 over thu 08:00 as end date :) if ($hoursRemaining == 0 && $full_working_day > 0) { $full_working_days--; $sgn > 0 ? $this->setHour($cal_day_start + $dwh) : $this->setHour($cal_day_end - $dwh); } else { $sgn > 0 ? $this->setHour($cal_day_start + $hoursRemaining) : $this->setHour($cal_day_end - $hoursRemaining); } //end of proceeding the last day } } // proceeding the fulldays finally which is easy // Full days for ($i = 0; $i < $full_working_days; $i++) { $this->addDays(1 * $sgn); if (!$this->isWorkingDay()) { // just 'ignore' this non-working day $full_working_days++; } } //end of proceeding the fulldays return $this->next_working_day(); }