@@ -96,6 +96,15 @@ protected static function process($expr, $time)
9696 );
9797 }
9898
99+ $ time = static ::normalizeTime ($ time );
100+
101+ $ time = array_map ('intval ' , explode (' ' , date ('i G j n w Y t d m N ' , $ time )));
102+
103+ return [$ expr , $ time ];
104+ }
105+
106+ protected static function normalizeTime ($ time )
107+ {
99108 if (empty ($ time )) {
100109 $ time = time ();
101110 } elseif (is_string ($ time )) {
@@ -104,9 +113,7 @@ protected static function process($expr, $time)
104113 $ time = $ time ->getTimestamp ();
105114 }
106115
107- $ time = array_map ('intval ' , explode (' ' , date ('i G j n w Y t d m N ' , $ time )));
108-
109- return [$ expr , $ time ];
116+ return $ time ;
110117 }
111118
112119 protected static function isSegmentDue ($ segment , $ pos , $ time )
@@ -207,17 +214,22 @@ protected static function checkMonthDay($value, $time)
207214 if ($ pos = strpos ($ value , 'W ' )) {
208215 $ value = substr ($ value , 0 , $ pos );
209216
210- foreach ([0 , -1 , 1 , -2 , 2 ] as $ i ) {
211- $ incr = $ value + $ i ;
212- if ($ incr > 0 && $ incr <= $ time [6 ]) {
213- if ($ incr < 10 ) {
214- $ incr = '0 ' . $ incr ;
215- }
216-
217- $ parts = explode (' ' , date ('N m j ' , strtotime ("$ time [5 ]- $ month- $ incr " )));
218- if ($ parts [0 ] < 6 && $ parts [1 ] == $ month ) {
219- return $ time [2 ] == $ parts [2 ];
220- }
217+ return static ::isClosestWeekDay ($ value , $ month , $ time );
218+ }
219+ }
220+
221+ protected function isClosestWeekDay ($ value , $ month , $ time )
222+ {
223+ foreach ([0 , -1 , 1 , -2 , 2 ] as $ i ) {
224+ $ incr = $ value + $ i ;
225+ if ($ incr > 0 && $ incr <= $ time [6 ]) {
226+ if ($ incr < 10 ) {
227+ $ incr = '0 ' . $ incr ;
228+ }
229+
230+ $ parts = explode (' ' , date ('N m j ' , strtotime ("$ time [5 ]- $ month- $ incr " )));
231+ if ($ parts [0 ] < 6 && $ parts [1 ] == $ month ) {
232+ return $ time [2 ] == $ parts [2 ];
221233 }
222234 }
223235 }
@@ -237,17 +249,8 @@ protected static function checkWeekDay($value, $time)
237249 {
238250 $ month = $ time [8 ] < 10 ? '0 ' . $ time [8 ] : $ time [8 ];
239251
240- if ($ pos = strpos ($ value , 'L ' )) {
241- $ value = explode ('L ' , str_replace ('7L ' , '0L ' , $ value ));
242- $ decr = $ time [6 ];
243- for ($ i = 0 ; $ i < 7 ; $ i ++) {
244- $ decr -= $ i ;
245- if (date ('w ' , strtotime ("$ time [5 ]- $ month- $ decr " )) == $ value [0 ]) {
246- return $ time [2 ] == $ decr ;
247- }
248- }
249-
250- return false ;
252+ if (strpos ($ value , 'L ' )) {
253+ return static ::lasWeekDay ($ value , $ month , $ time );
251254 }
252255
253256 if (strpos ($ value , '# ' )) {
@@ -261,6 +264,21 @@ protected static function checkWeekDay($value, $time)
261264 }
262265 }
263266
267+ protected static function lasWeekDay ($ value , $ month , $ time )
268+ {
269+ $ value = explode ('L ' , str_replace ('7L ' , '0L ' , $ value ));
270+ $ decr = $ time [6 ];
271+
272+ for ($ i = 0 ; $ i < 7 ; $ i ++) {
273+ $ decr -= $ i ;
274+ if (date ('w ' , strtotime ("$ time [5 ]- $ month- $ decr " )) == $ value [0 ]) {
275+ return $ time [2 ] == $ decr ;
276+ }
277+ }
278+
279+ return false ;
280+ }
281+
264282 /**
265283 * Instance call.
266284 *
0 commit comments