-
-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathExpression.php
More file actions
203 lines (174 loc) · 5.42 KB
/
Copy pathExpression.php
File metadata and controls
203 lines (174 loc) · 5.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
<?php
declare(strict_types=1);
/*
* This file is part of the PHP-CRON-EXPR package.
*
* (c) Jitendra Adhikari <jiten.adhikary@gmail.com>
* <https://github.com/adhocore>
*
* Licensed under MIT license.
*/
namespace Ahc\Cron;
use DateTime;
/**
* Cron Expression Parser.
*
* This class checks if a cron expression is due to run on given timestamp (or default now).
* Acknowledgement: The initial idea came from {@link http://stackoverflow.com/a/5727346}.
*
* @author Jitendra Adhikari <jiten.adhikary@gmail.com>
*/
class Expression
{
/** @var Expression */
protected static $instance;
/** @var SegmentChecker */
protected $checker;
/** @var Normalizer */
protected $normalizer;
/** @var Ticks */
protected $ticks;
public function __construct(SegmentChecker $checker = null, Normalizer $normalizer = null)
{
$this->checker = $checker ?: new SegmentChecker;
$this->normalizer = $normalizer ?: new Normalizer;
$this->ticks = new Ticks($this);
if (null === static::$instance) {
static::$instance = $this;
}
}
public static function instance(): self
{
if (null === static::$instance) {
static::$instance = new static;
}
return static::$instance;
}
/**
* Parse cron expression to decide if it can be run on given time (or default now).
*
* @param string $expr The cron expression.
* @param mixed $time The timestamp to validate the cron expr against. Defaults to now.
*
* @return bool
*/
public static function isDue(string $expr, $time = null): bool
{
return static::instance()->isCronDue($expr, $time);
}
/**
* Next DateTime when the expr would be due again.
*
* @param string $expr The cron expression.
* @param mixed $time The timestamp to validate the cron expr against. Defaults to now.
*
* @throws \RuntimeException
* @throws \UnexpectedValueException
*
* @return \DateTime
*/
public function nextTick(string $expr, $time = null): DateTime
{
return $this->ticks->next($expr, $time);
}
/**
* Next DateTime when the expr would be due again.
*
* @param string $expr The cron expression.
* @param mixed $time The timestamp to validate the cron expr against. Defaults to now.
*
* @throws \RuntimeException
* @throws \UnexpectedValueException
*
* @return \DateTime
*/
public static function next(string $expr, $time = null): DateTime
{
return static::instance()->nextTick($expr, $time);
}
/**
* Next date time as formatted string when the expr would be due again.
*
* @param string $expr The cron expression.
* @param mixed $time The timestamp to validate the cron expr against. Defaults to now.
* @param string $fmt The format
*
* @throws \RuntimeException
* @throws \UnexpectedValueException
*
* @return \DateTime
*/
public static function nextf(string $expr, $time = null, string $fmt = 'Y-m-d H:i:s'): string
{
return static::next($expr, $time)->format($fmt);
}
/**
* Filter only the jobs that are due.
*
* @param array $jobs Jobs with cron exprs. [job1 => cron-expr1, job2 => cron-expr2, ...]
* @param mixed $time The timestamp to validate the cron expr against. Defaults to now.
*
* @return array Due job names: [job1name, ...];
*/
public static function getDues(array $jobs, $time = null): array
{
return static::instance()->filter($jobs, $time);
}
/**
* Instance call.
*
* Parse cron expression to decide if it can be run on given time (or default now).
*
* @param string $expr The cron expression.
* @param mixed $time The timestamp to validate the cron expr against. Defaults to now.
*
* @return bool
*/
public function isCronDue(string $expr, $time = null): bool
{
return $this->segmentsDue($this->segments($expr), $time);
}
public function segmentsDue(array $segments, $time = null): bool
{
$this->checker->setReference(new ReferenceTime($time));
foreach ($segments as $pos => $segment) {
if ($segment === '*' || $segment === '?') {
continue;
}
if (!$this->checker->checkDue($segment, $pos)) {
return false;
}
}
return true;
}
public function segments(string $expr): array
{
return \explode(' ', $this->normalizer->normalizeExpr($expr));
}
public function segmentChecker(): SegmentChecker
{
return $this->checker;
}
/**
* Filter only the jobs that are due.
*
* @param array $jobs Jobs with cron exprs. [job1 => cron-expr1, job2 => cron-expr2, ...]
* @param mixed $time The timestamp to validate the cron expr against. Defaults to now.
*
* @return array Due job names: [job1name, ...];
*/
public function filter(array $jobs, $time = null): array
{
$dues = $cache = [];
foreach ($jobs as $name => $expr) {
$expr = $this->normalizer->normalizeExpr($expr);
if (!isset($cache[$expr])) {
$cache[$expr] = $this->isCronDue($expr, $time);
}
if ($cache[$expr]) {
$dues[] = $name;
}
}
return $dues;
}
}