From 5f112e7d0464d98282443b78870cdccabe42aae9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 28 Apr 2024 14:47:35 +0200 Subject: Adding upstream version 1:1.1.2. Signed-off-by: Daniel Baumann --- .../cron-expression/src/Cron/DayOfMonthField.php | 145 +++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 vendor/dragonmantank/cron-expression/src/Cron/DayOfMonthField.php (limited to 'vendor/dragonmantank/cron-expression/src/Cron/DayOfMonthField.php') diff --git a/vendor/dragonmantank/cron-expression/src/Cron/DayOfMonthField.php b/vendor/dragonmantank/cron-expression/src/Cron/DayOfMonthField.php new file mode 100644 index 0000000..d4552e0 --- /dev/null +++ b/vendor/dragonmantank/cron-expression/src/Cron/DayOfMonthField.php @@ -0,0 +1,145 @@ + + */ +class DayOfMonthField extends AbstractField +{ + /** + * @inheritDoc + */ + protected $rangeStart = 1; + + /** + * @inheritDoc + */ + protected $rangeEnd = 31; + + /** + * Get the nearest day of the week for a given day in a month + * + * @param int $currentYear Current year + * @param int $currentMonth Current month + * @param int $targetDay Target day of the month + * + * @return \DateTime Returns the nearest date + */ + private static function getNearestWeekday($currentYear, $currentMonth, $targetDay) + { + $tday = str_pad($targetDay, 2, '0', STR_PAD_LEFT); + $target = DateTime::createFromFormat('Y-m-d', "$currentYear-$currentMonth-$tday"); + $currentWeekday = (int) $target->format('N'); + + if ($currentWeekday < 6) { + return $target; + } + + $lastDayOfMonth = $target->format('t'); + + foreach (array(-1, 1, -2, 2) as $i) { + $adjusted = $targetDay + $i; + if ($adjusted > 0 && $adjusted <= $lastDayOfMonth) { + $target->setDate($currentYear, $currentMonth, $adjusted); + if ($target->format('N') < 6 && $target->format('m') == $currentMonth) { + return $target; + } + } + } + } + + /** + * @inheritDoc + */ + public function isSatisfiedBy(DateTimeInterface $date, $value) + { + // ? states that the field value is to be skipped + if ($value == '?') { + return true; + } + + $fieldValue = $date->format('d'); + + // Check to see if this is the last day of the month + if ($value == 'L') { + return $fieldValue == $date->format('t'); + } + + // Check to see if this is the nearest weekday to a particular value + if (strpos($value, 'W')) { + // Parse the target day + $targetDay = substr($value, 0, strpos($value, 'W')); + // Find out if the current day is the nearest day of the week + return $date->format('j') == self::getNearestWeekday( + $date->format('Y'), + $date->format('m'), + $targetDay + )->format('j'); + } + + return $this->isSatisfied($date->format('d'), $value); + } + + /** + * @inheritDoc + * + * @param \DateTime|\DateTimeImmutable &$date + */ + public function increment(DateTimeInterface &$date, $invert = false) + { + if ($invert) { + $date = $date->modify('previous day')->setTime(23, 59); + } else { + $date = $date->modify('next day')->setTime(0, 0); + } + + return $this; + } + + /** + * @inheritDoc + */ + public function validate($value) + { + $basicChecks = parent::validate($value); + + // Validate that a list don't have W or L + if (strpos($value, ',') !== false && (strpos($value, 'W') !== false || strpos($value, 'L') !== false)) { + return false; + } + + if (!$basicChecks) { + + if ($value === 'L') { + return true; + } + + if (preg_match('/^(.*)W$/', $value, $matches)) { + return $this->validate($matches[1]); + } + + return false; + } + + return $basicChecks; + } +} -- cgit v1.2.3