@@ -209,28 +209,127 @@ public function testOffsetDecrementsPreviousRunDate(): void
209
209
$ this ->assertEquals ($ dtExpected , $ cron ->getPreviousRunDate ($ dtCurrent , 0 , false , $ tz ->getName ()));
210
210
}
211
211
212
- public function testOffsetIncrementsMultipleRunDates (): void
212
+ public static function dayLightSavingExamples (): \ Generator
213
213
{
214
- $ expression = "0 1 * * 0 " ;
215
- $ cron = new CronExpression ($ expression );
216
- $ tz = new \DateTimeZone ("Europe/London " );
214
+ yield 'fixed hour before turnover point ' => [
215
+ "0 1 * * 0 " ,
216
+ [
217
+ "2021-03-14 01:00+00:00 " ,
218
+ "2021-03-21 01:00+00:00 " ,
219
+ "2021-03-28 02:00+01:00 " ,
220
+ "2021-04-04 01:00+01:00 " ,
221
+ "2021-04-11 01:00+01:00 " ,
222
+ ],
223
+ new \DateTimeZone ("Europe/London " ),
224
+ "2021-03-13 00:00+00:00 " ,
225
+ "2021-04-12 00:00+01:00 " ,
226
+ ];
217
227
218
- $ expected = [
219
- $ this ->createDateTimeExactly ("2021-03-14 01:00+00:00 " , $ tz ),
220
- $ this ->createDateTimeExactly ("2021-03-21 01:00+00:00 " , $ tz ),
221
- $ this ->createDateTimeExactly ("2021-03-28 02:00+01:00 " , $ tz ),
222
- $ this ->createDateTimeExactly ("2021-04-04 01:00+01:00 " , $ tz ),
223
- $ this ->createDateTimeExactly ("2021-04-11 01:00+01:00 " , $ tz ),
228
+ yield 'fixed hour expression while daylight saving is starting (#154) ' => [
229
+ "30 07 * * * " ,
230
+ [
231
+ "2023-03-11 07:30-05:00 " ,
232
+ "2023-03-12 07:30-04:00 " ,
233
+ "2023-03-13 07:30-04:00 " ,
234
+ ],
235
+ new \DateTimeZone ("America/New_York " ),
236
+ "2023-03-10 08:00-05:00 " ,
237
+ "2023-03-13 08:00-04:00 " ,
224
238
];
225
239
226
- $ dtCurrent = $ this ->createDateTimeExactly ("2021-03-13 00:00+00:00 " , $ tz );
227
- $ actual = $ cron ->getMultipleRunDates (5 , $ dtCurrent , false , true , $ tz ->getName ());
240
+ yield 'fixed hour expression while daylight saving is starting (#202) ' => [
241
+ "0 10 * * * " ,
242
+ [
243
+ "2025-03-08 10:00-06:00 " ,
244
+ "2025-03-09 10:00-05:00 " ,
245
+ "2025-03-10 10:00-05:00 " ,
246
+ ],
247
+ new \DateTimeZone ("America/Chicago " ),
248
+ "2025-03-08 09:00-06:00 " ,
249
+ "2025-03-10 11:00-05:00 " ,
250
+ ];
251
+
252
+ yield 'fixed hour expression while daylight saving is ending ' => [
253
+ "0 10 * * * " ,
254
+ [
255
+ "2025-11-01 10:00-05:00 " ,
256
+ "2025-11-02 10:00-06:00 " ,
257
+ "2025-11-03 10:00-06:00 " ,
258
+ ],
259
+ new \DateTimeZone ("America/Chicago " ),
260
+ "2025-11-01 09:00-05:00 " ,
261
+ "2025-11-03 11:00-06:00 " ,
262
+ ];
263
+
264
+ yield 'every hour expression while daylight saving is starting ' => [
265
+ "30 */1 * * * " ,
266
+ [
267
+ "2025-03-09 00:30-06:00 " ,
268
+ "2025-03-09 01:30-06:00 " ,
269
+ "2025-03-09 03:30-05:00 " ,
270
+ "2025-03-09 04:30-05:00 " ,
271
+ ],
272
+ new \DateTimeZone ("America/Chicago " ),
273
+ "2025-03-09 00:00-06:00 " ,
274
+ "2025-03-09 05:00-05:00 " ,
275
+ ];
276
+
277
+ yield 'every hour expression while daylight saving is ending ' => [
278
+ "30 */1 * * * " ,
279
+ [
280
+ "2025-11-02 00:30-05:00 " ,
281
+ "2025-11-02 01:30-05:00 " ,
282
+ "2025-11-02 01:30-06:00 " ,
283
+ "2025-11-02 02:30-06:00 " ,
284
+ ],
285
+ new \DateTimeZone ("America/Chicago " ),
286
+ "2025-11-02 00:00-05:00 " ,
287
+ "2025-11-02 03:00-06:00 " ,
288
+ ];
289
+
290
+ yield 'fixed time expression inside the daylight transition hour ' => [
291
+ "30 2 * * * " ,
292
+ [
293
+ "2025-03-08 02:30-06:00 " ,
294
+ "2025-03-09 03:30-05:00 " ,
295
+ "2025-03-10 02:30-05:00 " ,
296
+ ],
297
+ new \DateTimeZone ("America/Chicago " ),
298
+ "2025-03-08 01:30-06:00 " ,
299
+ "2025-03-10 11:00-05:00 " ,
300
+ ];
301
+ }
302
+
303
+ /**
304
+ * @param string[] $expected
305
+ *
306
+ * @dataProvider dayLightSavingExamples
307
+ */
308
+ public function testOffsetIncrementsMultipleRunDates (
309
+ string $ expression ,
310
+ array $ expected ,
311
+ \DateTimeZone $ tz ,
312
+ string $ currentDate ,
313
+ string $ currentInvertedDate
314
+ ): void {
315
+ $ cron = new CronExpression ($ expression );
316
+
317
+ $ expected = array_map (
318
+ function (string $ dtString ) use ($ tz ) {
319
+ return $ this ->createDateTimeExactly ($ dtString , $ tz );
320
+ },
321
+ $ expected
322
+ );
323
+ $ total = count ($ expected );
324
+
325
+ $ dtCurrent = $ this ->createDateTimeExactly ($ currentDate , $ tz );
326
+ $ actual = $ cron ->getMultipleRunDates ($ total , $ dtCurrent , false , true , $ tz ->getName ());
228
327
foreach ($ expected as $ dtExpected ) {
229
328
$ this ->assertContainsEquals ($ dtExpected , $ actual );
230
329
}
231
330
232
- $ dtCurrent = $ this ->createDateTimeExactly (" 2021-04-12 00:00+01:00 " , $ tz );
233
- $ actual = $ cron ->getMultipleRunDates (5 , $ dtCurrent , true , true , $ tz ->getName ());
331
+ $ dtCurrent = $ this ->createDateTimeExactly ($ currentInvertedDate , $ tz );
332
+ $ actual = $ cron ->getMultipleRunDates ($ total , $ dtCurrent , true , true , $ tz ->getName ());
234
333
foreach ($ expected as $ dtExpected ) {
235
334
$ this ->assertContainsEquals ($ dtExpected , $ actual );
236
335
}
0 commit comments