1<?php 2 3namespace Cron; 4use DateTime; 5use DateTimeZone; 6 7 8/** 9 * Hours field. Allows: * , / - 10 */ 11class HoursField extends AbstractField 12{ 13 public function isSatisfiedBy(DateTime $date, $value) 14 { 15 return $this->isSatisfied($date->format('H'), $value); 16 } 17 18 public function increment(DateTime $date, $invert = false, $parts = null) 19 { 20 // Change timezone to UTC temporarily. This will 21 // allow us to go back or forwards and hour even 22 // if DST will be changed between the hours. 23 if (is_null($parts) || $parts == '*') { 24 $timezone = $date->getTimezone(); 25 $date->setTimezone(new DateTimeZone('UTC')); 26 if ($invert) { 27 $date->modify('-1 hour'); 28 } else { 29 $date->modify('+1 hour'); 30 } 31 $date->setTimezone($timezone); 32 33 $date->setTime($date->format('H'), $invert ? 59 : 0); 34 return $this; 35 } 36 37 $parts = strpos($parts, ',') !== false ? explode(',', $parts) : array($parts); 38 $hours = array(); 39 foreach ($parts as $part) { 40 $hours = array_merge($hours, $this->getRangeForExpression($part, 23)); 41 } 42 43 $current_hour = $date->format('H'); 44 $position = $invert ? count($hours) - 1 : 0; 45 if (count($hours) > 1) { 46 for ($i = 0; $i < count($hours) - 1; $i++) { 47 if ((!$invert && $current_hour >= $hours[$i] && $current_hour < $hours[$i + 1]) || 48 ($invert && $current_hour > $hours[$i] && $current_hour <= $hours[$i + 1])) { 49 $position = $invert ? $i : $i + 1; 50 break; 51 } 52 } 53 } 54 55 $hour = $hours[$position]; 56 if ((!$invert && $date->format('H') >= $hour) || ($invert && $date->format('H') <= $hour)) { 57 $date->modify(($invert ? '-' : '+') . '1 day'); 58 $date->setTime($invert ? 23 : 0, $invert ? 59 : 0); 59 } 60 else { 61 $date->setTime($hour, $invert ? 59 : 0); 62 } 63 64 return $this; 65 } 66 67 public function validate($value) 68 { 69 return (bool) preg_match('/^[\*,\/\-0-9]+$/', $value); 70 } 71} 72