/** * Get the difference by the given interval using a filter closure. * The callback will be called for each period in the given time frame. If the callback returns true the period is * included as difference, false should be returned otherwise. * * @param DateInterval|PHPDateInterval|string|null $dateInterval A DateInterval or PHPDateInterval instance, the * date interval specification as a string, the date interval relative date and time as a string or null to use * a zero date interval. * @param Closure $callback The callback function to call for each period as filter. * @param DateTime|PHPDateTime|string|null $dateTime [optional] The DateTime or PHPDateTime instance, the date and * time as a string or null to use the now() date and time. * @param boolean $absolute [optional] True to get the absolute difference, false otherwise. * * @return int|null The difference of the date interval in the given time frame. Null will be returned on failure. */ public function diffFiltered($dateInterval, Closure $callback, $dateTime = null, $absolute = true) { // Parse the date interval, return null on failure if (($dateInterval = DateInterval::parse($dateInterval)) === null) { return null; } // Parse the date and time, return null on failure if (($dateTime = static::parse($dateTime, $this->getTimezone())) === null) { return null; } // Define the start and end times, define whether the value should be inverted $inverse = !$this->isLessThan($dateTime); $start = $inverse ? $this : $dateTime; $end = $inverse ? $dateTime : $start; // Run the callback for all periods $period = new DatePeriod($start, $dateInterval, $end); $values = array_filter(iterator_to_array($period), function (DateTime $date) use($callback) { return call_user_func($callback, DateTime::instance($date)); }); // Get the difference result $diff = count($values); // Return the difference result, inverse the value if needed return $inverse && !$absolute ? $diff * -1 : $diff; }
/** * Parse a date interval. A new instance may be created. * * This method allows better fluent syntax because it makes method chaining possible. * * @param DateInterval|PHPDateInterval|string|null $dateInterval [optional] A DateInterval or PHPDateInterval * instance, a date interval specification, or null to use a zero specification. * @param mixed|null $default [optional] The default value to be returned on failure. * * @return static|mixed A DateInterval instance, or the default value on failure. */ public static function parse($dateInterval, $default = null) { return ($result = DateInterval::parse($dateInterval)) === null ? $default : $result; }