current-weekday, so do modulo calc $offset = (date('w', $curr_time) - $first_weekdayid + 7) % 7; $span['begin_now'] = (int) strtotime('-' . $offset . ' days' . date('Y-m-d', $curr_time)); $span['end_now'] = strtotime('+1 week', $span['begin_now']) - 1; break; case GT_THIS_MONTH: // this date format set day-of-month to 01 $span['begin_now'] = (int) strtotime(date('Y-m-01', $curr_time)); $span['end_now'] = strtotime('+1 month', $span['begin_now']) - 1; break; case GT_THIS_YEAR: // this date format set day-of-month to 01 and month-of-year to 01 $span['begin_now'] = (int) strtotime(date('Y-01-01', $curr_time)); $span['end_now'] = strtotime('+1 year', $span['begin_now']) - 1; break; case GT_PREV_DAY: $span['begin_now'] = (int) strtotime('-1 day' . date('Y-m-d', $curr_time)); $span['end_now'] = strtotime('+1 day', $span['begin_now']) - 1; break; case GT_PREV_WEEK: // compute offset to start-of-week // remember: start-of-week may be > current-weekday, so do modulo calc $offset = (date('w',$curr_time) - $first_weekdayid + 7) % 7; $span['begin_now'] = (int) strtotime('-1 week -' . $offset . ' days' . date('Y-m-d', $curr_time)); $span['end_now'] = strtotime('+1 week', $span['begin_now']) - 1; break; case GT_PREV_MONTH: $span['begin_now'] = (int) strtotime('-1 month' . date('Y-m-01', $curr_time)); $span['end_now'] = strtotime('+1 month', $span['begin_now']) - 1; break; case GT_PREV_YEAR: $span['begin_now'] = (int) strtotime('-1 year' . date('Y-01-01', $curr_time)); $span['end_now'] = strtotime('+1 year', $span['begin_now']) - 1; break; default: $span['begin_now'] = $curr_time - DEFAULT_TIMESPAN; break; } // reformat time-since-epoch start/end times to human readable format $span['current_value_date1'] = date('Y-m-d H:i', (int) $span['begin_now']); $span['current_value_date2'] = date('Y-m-d H:i', (int) $span['end_now']); } /** * month_shift - check for shifting one or more months * * @param string $shift_size The requested shift amount * * @return bool True, if month shifting required, else false */ function month_shift(string $shift_size) : bool { // is monthly shifting required? return (str_contains(cacti_strtolower($shift_size), 'month')); } /** * check_month_boundaries - check given boundaries for begin/end of month matching * * @param array $span A $timespan array with given boundaries * * @return bool True, if begin AND end match month begin/end boundaries */ function check_month_boundaries(array &$span) : bool { // check left boundary ----------------------------------------------- $begin_of_month = (int) strtotime(date('Y-m-01', $span['begin_now'])); $begin_match = ($begin_of_month == $span['begin_now']); // check right boundary ---------------------------------------------- // first, get a defined date of the month, $span['end_now'] belongs to $begin_of_month = (int) strtotime(date('Y-m-01', $span['end_now'])); // do "end of month" magic to get end_of_month for arbitrary months $end_of_month = (int) strtotime('+1 month', $begin_of_month) - 1; // accept end of month if no seconds given (adjust for 59 missing seconds) $end_match = ((($end_of_month - 59) <= $span['end_now']) && ($span['end_now'] <= $end_of_month)); return ($begin_match && $end_match); } /** * shift_right_boundary - shift right boundary with end-of-month adjustment * * @param array $span The timespan array * @param string $direction A shift left/right (-/+) * @param mixed $shift_size The amount of shift * * @return int Time-since-epoch for shifted right boundary */ function shift_right_boundary(array &$span, string $direction, mixed $shift_size) : int { // first, get begin of the month, $span['end_now'] belongs to $begin = date('Y-m-01', $span['end_now']); // shift the begin date to correct month $begin_of_shifted_month = (int) strtotime($direction . $shift_size . ' ' . $begin); // do "end of month" magic return strtotime('+1 month', $begin_of_shifted_month) - 1; } /** * shift_time - shift given timespan left/right * * @param array &$span A given timespan (start/end time as time-since-epoch and human readable) * @param string $direction The direction either "-" for shifting left, "+" for shifting right * @param mixed $shift_size An amount of shifting * * @return void */ function shift_time(array &$span, string $direction, mixed $shift_size) : void { // move left/right according to $direction // amount to be moved is derived from $shift_size // base dates are taken from array $span // is this a month shift AND current timespan is on month boundaries? if (month_shift($shift_size) && check_month_boundaries($span)) { // shift left boundary $span['begin_now'] = strtotime($direction . $shift_size . ' ' . $span['current_value_date1']); // shifting right boundary is somewhat complicated $span['end_now'] = shift_right_boundary($span, $direction, $shift_size); } else { // 'normal' time shifting: use strtotime magic $span['begin_now'] = strtotime($direction . $shift_size . ' ' . $span['current_value_date1']); $span['end_now'] = (int) strtotime($direction . $shift_size . ' ' . $span['current_value_date2']); } // convert to human readable format $span['current_value_date1'] = date('Y-m-d H:i', $span['begin_now']); $span['current_value_date2'] = date('Y-m-d H:i', $span['end_now']); // now custom time settings in effect $_SESSION['sess_current_timespan'] = GT_CUSTOM; $_SESSION['custom'] = 1; srv('predefined_timespan', GT_CUSTOM); }