Skip to content

Commit 4d7bacd

Browse files
Merge pull request mtdowling#41 from cmorbitzer/support-datetimeimmutable
Support DateTimeImmutable
2 parents 714f6a8 + c38f254 commit 4d7bacd

13 files changed

+204
-87
lines changed

src/Cron/CronExpression.php

+31-30
Original file line numberDiff line numberDiff line change
@@ -179,16 +179,17 @@ public function setMaxIterationCount($maxIterationCount)
179179
/**
180180
* Get a next run date relative to the current date or a specific date
181181
*
182-
* @param string|\DateTime $currentTime Relative calculation date
183-
* @param int $nth Number of matches to skip before returning a
184-
* matching next run date. 0, the default, will return the current
185-
* date and time if the next run date falls on the current date and
186-
* time. Setting this value to 1 will skip the first match and go to
187-
* the second match. Setting this value to 2 will skip the first 2
188-
* matches and so on.
189-
* @param bool $allowCurrentDate Set to TRUE to return the current date if
190-
* it matches the cron expression.
191-
* @param null|string $timeZone TimeZone to use instead of the system default
182+
* @param string|\DateTimeInterface $currentTime Relative calculation date
183+
* @param int $nth Number of matches to skip before returning a
184+
* matching next run date. 0, the default, will return the
185+
* current date and time if the next run date falls on the
186+
* current date and time. Setting this value to 1 will
187+
* skip the first match and go to the second match.
188+
* Setting this value to 2 will skip the first 2
189+
* matches and so on.
190+
* @param bool $allowCurrentDate Set to TRUE to return the current date if
191+
* it matches the cron expression.
192+
* @param null|string $timeZone TimeZone to use instead of the system default
192193
*
193194
* @return \DateTime
194195
* @throws \RuntimeException on too many iterations
@@ -201,11 +202,11 @@ public function getNextRunDate($currentTime = 'now', $nth = 0, $allowCurrentDate
201202
/**
202203
* Get a previous run date relative to the current date or a specific date
203204
*
204-
* @param string|\DateTime $currentTime Relative calculation date
205-
* @param int $nth Number of matches to skip before returning
206-
* @param bool $allowCurrentDate Set to TRUE to return the
207-
* current date if it matches the cron expression
208-
* @param null|string $timeZone TimeZone to use instead of the system default
205+
* @param string|\DateTimeInterface $currentTime Relative calculation date
206+
* @param int $nth Number of matches to skip before returning
207+
* @param bool $allowCurrentDate Set to TRUE to return the
208+
* current date if it matches the cron expression
209+
* @param null|string $timeZone TimeZone to use instead of the system default
209210
*
210211
* @return \DateTime
211212
* @throws \RuntimeException on too many iterations
@@ -219,14 +220,14 @@ public function getPreviousRunDate($currentTime = 'now', $nth = 0, $allowCurrent
219220
/**
220221
* Get multiple run dates starting at the current date or a specific date
221222
*
222-
* @param int $total Set the total number of dates to calculate
223-
* @param string|\DateTime $currentTime Relative calculation date
224-
* @param bool $invert Set to TRUE to retrieve previous dates
225-
* @param bool $allowCurrentDate Set to TRUE to return the
226-
* current date if it matches the cron expression
227-
* @param null|string $timeZone TimeZone to use instead of the system default
223+
* @param int $total Set the total number of dates to calculate
224+
* @param string|\DateTimeInterface $currentTime Relative calculation date
225+
* @param bool $invert Set to TRUE to retrieve previous dates
226+
* @param bool $allowCurrentDate Set to TRUE to return the
227+
* current date if it matches the cron expression
228+
* @param null|string $timeZone TimeZone to use instead of the system default
228229
*
229-
* @return array Returns an array of run dates
230+
* @return \DateTime[] Returns an array of run dates
230231
*/
231232
public function getMultipleRunDates($total, $currentTime = 'now', $invert = false, $allowCurrentDate = false, $timeZone = null)
232233
{
@@ -277,8 +278,8 @@ public function __toString()
277278
* specific date. This method assumes that the current number of
278279
* seconds are irrelevant, and should be called once per minute.
279280
*
280-
* @param string|\DateTime $currentTime Relative calculation date
281-
* @param null|string $timeZone TimeZone to use instead of the system default
281+
* @param string|\DateTimeInterface $currentTime Relative calculation date
282+
* @param null|string $timeZone TimeZone to use instead of the system default
282283
*
283284
* @return bool Returns TRUE if the cron is due to run or FALSE if not
284285
*/
@@ -310,12 +311,12 @@ public function isDue($currentTime = 'now', $timeZone = null)
310311
/**
311312
* Get the next or previous run date of the expression relative to a date
312313
*
313-
* @param string|\DateTime $currentTime Relative calculation date
314-
* @param int $nth Number of matches to skip before returning
315-
* @param bool $invert Set to TRUE to go backwards in time
316-
* @param bool $allowCurrentDate Set to TRUE to return the
317-
* current date if it matches the cron expression
318-
* @param string|null $timeZone TimeZone to use instead of the system default
314+
* @param string|\DateTimeInterface $currentTime Relative calculation date
315+
* @param int $nth Number of matches to skip before returning
316+
* @param bool $invert Set to TRUE to go backwards in time
317+
* @param bool $allowCurrentDate Set to TRUE to return the
318+
* current date if it matches the cron expression
319+
* @param string|null $timeZone TimeZone to use instead of the system default
319320
*
320321
* @return \DateTime
321322
* @throws \RuntimeException on too many iterations

src/Cron/DayOfMonthField.php

+7-6
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Cron;
44

55
use DateTime;
6+
use DateTimeInterface;
67

78
/**
89
* Day of month field. Allows: * , / - ? L W
@@ -69,7 +70,7 @@ private static function getNearestWeekday($currentYear, $currentMonth, $targetDa
6970
/**
7071
* @inheritDoc
7172
*/
72-
public function isSatisfiedBy(DateTime $date, $value)
73+
public function isSatisfiedBy(DateTimeInterface $date, $value)
7374
{
7475
// ? states that the field value is to be skipped
7576
if ($value == '?') {
@@ -100,15 +101,15 @@ public function isSatisfiedBy(DateTime $date, $value)
100101

101102
/**
102103
* @inheritDoc
104+
*
105+
* @param \DateTime|\DateTimeImmutable &$date
103106
*/
104-
public function increment(DateTime $date, $invert = false)
107+
public function increment(DateTimeInterface &$date, $invert = false)
105108
{
106109
if ($invert) {
107-
$date->modify('previous day');
108-
$date->setTime(23, 59);
110+
$date = $date->modify('previous day')->setTime(23, 59);
109111
} else {
110-
$date->modify('next day');
111-
$date->setTime(0, 0);
112+
$date = $date->modify('next day')->setTime(0, 0);
112113
}
113114

114115
return $this;

src/Cron/DayOfWeekField.php

+12-9
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Cron;
44

55
use DateTime;
6+
use DateTimeInterface;
67
use InvalidArgumentException;
78

89
/**
@@ -51,8 +52,10 @@ public function __construct()
5152

5253
/**
5354
* @inheritDoc
55+
*
56+
* @param \DateTime|\DateTimeImmutable $date
5457
*/
55-
public function isSatisfiedBy(DateTime $date, $value)
58+
public function isSatisfiedBy(DateTimeInterface $date, $value)
5659
{
5760
if ($value == '?') {
5861
return true;
@@ -71,7 +74,7 @@ public function isSatisfiedBy(DateTime $date, $value)
7174
$weekday = str_replace('7', '0', $weekday);
7275

7376
$tdate = clone $date;
74-
$tdate->setDate($currentYear, $currentMonth, $lastDayOfMonth);
77+
$tdate = $tdate->setDate($currentYear, $currentMonth, $lastDayOfMonth);
7578
while ($tdate->format('w') != $weekday) {
7679
$tdateClone = new DateTime();
7780
$tdate = $tdateClone
@@ -114,7 +117,7 @@ public function isSatisfiedBy(DateTime $date, $value)
114117
}
115118

116119
$tdate = clone $date;
117-
$tdate->setDate($currentYear, $currentMonth, 1);
120+
$tdate = $tdate->setDate($currentYear, $currentMonth, 1);
118121
$dayCount = 0;
119122
$currentDay = 1;
120123
while ($currentDay < $lastDayOfMonth + 1) {
@@ -123,7 +126,7 @@ public function isSatisfiedBy(DateTime $date, $value)
123126
break;
124127
}
125128
}
126-
$tdate->setDate($currentYear, $currentMonth, ++$currentDay);
129+
$tdate = $tdate->setDate($currentYear, $currentMonth, ++$currentDay);
127130
}
128131

129132
return $date->format('j') == $currentDay;
@@ -149,15 +152,15 @@ public function isSatisfiedBy(DateTime $date, $value)
149152

150153
/**
151154
* @inheritDoc
155+
*
156+
* @param \DateTime|\DateTimeImmutable &$date
152157
*/
153-
public function increment(DateTime $date, $invert = false)
158+
public function increment(DateTimeInterface &$date, $invert = false)
154159
{
155160
if ($invert) {
156-
$date->modify('-1 day');
157-
$date->setTime(23, 59, 0);
161+
$date = $date->modify('-1 day')->setTime(23, 59, 0);
158162
} else {
159-
$date->modify('+1 day');
160-
$date->setTime(0, 0, 0);
163+
$date = $date->modify('+1 day')->setTime(0, 0, 0);
161164
}
162165

163166
return $this;

src/Cron/FieldInterface.php

+7-7
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace Cron;
44

5-
use DateTime;
5+
use DateTimeInterface;
66

77
/**
88
* CRON field interface
@@ -12,23 +12,23 @@ interface FieldInterface
1212
/**
1313
* Check if the respective value of a DateTime field satisfies a CRON exp
1414
*
15-
* @param DateTime $date DateTime object to check
16-
* @param string $value CRON expression to test against
15+
* @param DateTimeInterface $date DateTime object to check
16+
* @param string $value CRON expression to test against
1717
*
1818
* @return bool Returns TRUE if satisfied, FALSE otherwise
1919
*/
20-
public function isSatisfiedBy(DateTime $date, $value);
20+
public function isSatisfiedBy(DateTimeInterface $date, $value);
2121

2222
/**
2323
* When a CRON expression is not satisfied, this method is used to increment
2424
* or decrement a DateTime object by the unit of the cron field
2525
*
26-
* @param DateTime $date DateTime object to change
27-
* @param bool $invert (optional) Set to TRUE to decrement
26+
* @param DateTimeInterface &$date DateTime object to change
27+
* @param bool $invert (optional) Set to TRUE to decrement
2828
*
2929
* @return FieldInterface
3030
*/
31-
public function increment(DateTime $date, $invert = false);
31+
public function increment(DateTimeInterface &$date, $invert = false);
3232

3333
/**
3434
* Validates a CRON expression for a given field

src/Cron/HoursField.php

+16-15
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace Cron;
44

5-
use DateTime;
5+
use DateTimeInterface;
66
use DateTimeZone;
77

88
/**
@@ -23,32 +23,33 @@ class HoursField extends AbstractField
2323
/**
2424
* @inheritDoc
2525
*/
26-
public function isSatisfiedBy(DateTime $date, $value)
26+
public function isSatisfiedBy(DateTimeInterface $date, $value)
2727
{
28+
if ($value == '?') {
29+
return true;
30+
}
31+
2832
return $this->isSatisfied($date->format('H'), $value);
2933
}
3034

3135
/**
3236
* {@inheritDoc}
3337
*
34-
* @param string|null $parts
38+
* @param \DateTime|\DateTimeImmutable &$date
39+
* @param string|null $parts
3540
*/
36-
public function increment(DateTime $date, $invert = false, $parts = null)
41+
public function increment(DateTimeInterface &$date, $invert = false, $parts = null)
3742
{
3843
// Change timezone to UTC temporarily. This will
3944
// allow us to go back or forwards and hour even
4045
// if DST will be changed between the hours.
4146
if (is_null($parts) || $parts == '*') {
4247
$timezone = $date->getTimezone();
43-
$date->setTimezone(new DateTimeZone('UTC'));
44-
if ($invert) {
45-
$date->modify('-1 hour');
46-
} else {
47-
$date->modify('+1 hour');
48-
}
49-
$date->setTimezone($timezone);
48+
$date = $date->setTimezone(new DateTimeZone('UTC'));
49+
$date = $date->modify(($invert ? '-' : '+') . '1 hour');
50+
$date = $date->setTimezone($timezone);
5051

51-
$date->setTime($date->format('H'), $invert ? 59 : 0);
52+
$date = $date->setTime($date->format('H'), $invert ? 59 : 0);
5253
return $this;
5354
}
5455

@@ -72,11 +73,11 @@ public function increment(DateTime $date, $invert = false, $parts = null)
7273

7374
$hour = $hours[$position];
7475
if ((!$invert && $date->format('H') >= $hour) || ($invert && $date->format('H') <= $hour)) {
75-
$date->modify(($invert ? '-' : '+') . '1 day');
76-
$date->setTime($invert ? 23 : 0, $invert ? 59 : 0);
76+
$date = $date->modify(($invert ? '-' : '+') . '1 day');
77+
$date = $date->setTime($invert ? 23 : 0, $invert ? 59 : 0);
7778
}
7879
else {
79-
$date->setTime($hour, $invert ? 59 : 0);
80+
$date = $date->setTime($hour, $invert ? 59 : 0);
8081
}
8182

8283
return $this;

src/Cron/MinutesField.php

+13-12
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace Cron;
44

5-
use DateTime;
5+
use DateTimeInterface;
66

77
/**
88
* Minutes field. Allows: * , / -
@@ -22,24 +22,25 @@ class MinutesField extends AbstractField
2222
/**
2323
* @inheritDoc
2424
*/
25-
public function isSatisfiedBy(DateTime $date, $value)
25+
public function isSatisfiedBy(DateTimeInterface $date, $value)
2626
{
27+
if ($value == '?') {
28+
return true;
29+
}
30+
2731
return $this->isSatisfied($date->format('i'), $value);
2832
}
2933

3034
/**
3135
* {@inheritDoc}
3236
*
33-
* @param string|null $parts
37+
* @param \DateTime|\DateTimeImmutable &$date
38+
* @param string|null $parts
3439
*/
35-
public function increment(DateTime $date, $invert = false, $parts = null)
40+
public function increment(DateTimeInterface &$date, $invert = false, $parts = null)
3641
{
3742
if (is_null($parts)) {
38-
if ($invert) {
39-
$date->modify('-1 minute');
40-
} else {
41-
$date->modify('+1 minute');
42-
}
43+
$date = $date->modify(($invert ? '-' : '+') . '1 minute');
4344
return $this;
4445
}
4546

@@ -62,11 +63,11 @@ public function increment(DateTime $date, $invert = false, $parts = null)
6263
}
6364

6465
if ((!$invert && $current_minute >= $minutes[$position]) || ($invert && $current_minute <= $minutes[$position])) {
65-
$date->modify(($invert ? '-' : '+') . '1 hour');
66-
$date->setTime($date->format('H'), $invert ? 59 : 0);
66+
$date = $date->modify(($invert ? '-' : '+') . '1 hour');
67+
$date = $date->setTime($date->format('H'), $invert ? 59 : 0);
6768
}
6869
else {
69-
$date->setTime($date->format('H'), $minutes[$position]);
70+
$date = $date->setTime($date->format('H'), $minutes[$position]);
7071
}
7172

7273
return $this;

0 commit comments

Comments
 (0)