diff --git a/extra/crontab/crontab-tests.factor b/extra/crontab/crontab-tests.factor index b3749f9435..e329be35ac 100644 --- a/extra/crontab/crontab-tests.factor +++ b/extra/crontab/crontab-tests.factor @@ -1,47 +1,131 @@ -USING: calendar crontab kernel math.order tools.test ; +USING: calendar calendar.format crontab kernel math.order +sequences tools.test ; -{ - T{ timestamp - { year 2018 } - { month 3 } - { day 9 } - { hour 12 } - { minute 23 } - { gmt-offset T{ duration { hour -8 } } } - } -} [ - "23 0-20/2 * * *" parse-cronentry - T{ timestamp - { year 2018 } - { month 3 } - { day 9 } - { hour 12 } - { minute 6 } - { gmt-offset T{ duration { hour -8 } } } - } next-time-after -] unit-test +IN: crontab.tests { +lt+ } [ now "*/1 * * * *" parse-cronentry next-time <=> ] unit-test +CONSTANT: start-timestamp T{ timestamp + { year 2019 } + { month 3 } + { day 23 } + { hour 14 } + { second 16+4353/8000 } + { gmt-offset T{ duration { hour -7 } } } +} + +: next-few-times ( pattern -- timestamps ) + parse-cronentry 5 start-timestamp next-times-after + [ timestamp>rfc822 ] map ; + +! At 04:05. { - T{ timestamp - { year 2019 } - { month 8 } - { day 1 } - { minute 5 } - { gmt-offset T{ duration { hour -7 } } } + { + "Sun, 24 Mar 2019 04:05:00 -0700" + "Mon, 25 Mar 2019 04:05:00 -0700" + "Tue, 26 Mar 2019 04:05:00 -0700" + "Wed, 27 Mar 2019 04:05:00 -0700" + "Thu, 28 Mar 2019 04:05:00 -0700" } -} [ - "5 0 * 8 *" parse-cronentry - T{ timestamp - { year 2019 } - { month 3 } - { day 22 } - { hour 15 } - { minute 16 } - { second 36+590901/1000000 } - { gmt-offset T{ duration { hour -7 } } } - } next-time-after -] unit-test +} [ "5 4 * * *" next-few-times ] unit-test + +! At 00:05 in August. +{ + { + "Thu, 1 Aug 2019 00:05:00 -0700" + "Fri, 2 Aug 2019 00:05:00 -0700" + "Sat, 3 Aug 2019 00:05:00 -0700" + "Sun, 4 Aug 2019 00:05:00 -0700" + "Mon, 5 Aug 2019 00:05:00 -0700" + } +} [ "5 0 * 8 *" next-few-times ] unit-test + +! At 14:15 on day-of-month 1. +{ + { + "Mon, 1 Apr 2019 14:15:00 -0700" + "Wed, 1 May 2019 14:15:00 -0700" + "Sat, 1 Jun 2019 14:15:00 -0700" + "Mon, 1 Jul 2019 14:15:00 -0700" + "Thu, 1 Aug 2019 14:15:00 -0700" + } +} [ "15 14 1 * *" next-few-times ] unit-test + +! At 22:00 on every day-of-week from Monday through Friday. +{ + { + "Mon, 25 Mar 2019 22:00:00 -0700" + "Tue, 26 Mar 2019 22:00:00 -0700" + "Wed, 27 Mar 2019 22:00:00 -0700" + "Thu, 28 Mar 2019 22:00:00 -0700" + "Fri, 29 Mar 2019 22:00:00 -0700" + } +} [ "0 22 * * 1-5" next-few-times ] unit-test + +! At minute 23 past every 2nd hour from 0 through 20. +{ + { + "Sat, 23 Mar 2019 14:23:00 -0700" + "Sat, 23 Mar 2019 16:23:00 -0700" + "Sat, 23 Mar 2019 18:23:00 -0700" + "Sat, 23 Mar 2019 20:23:00 -0700" + "Sun, 24 Mar 2019 00:23:00 -0700" + } +} [ "23 0-20/2 * * *" next-few-times ] unit-test + +! At 04:05 on Sunday. +{ + { + "Sun, 24 Mar 2019 04:05:00 -0700" + "Sun, 31 Mar 2019 04:05:00 -0700" + "Sun, 7 Apr 2019 04:05:00 -0700" + "Sun, 14 Apr 2019 04:05:00 -0700" + "Sun, 21 Apr 2019 04:05:00 -0700" + } +} [ "5 4 * * sun" next-few-times ] unit-test + +! At minute 0 past hour 0 and 12 on day-of-month 1 in every 2nd month. +{ + { + "Wed, 1 May 2019 00:00:00 -0700" + "Wed, 1 May 2019 12:00:00 -0700" + "Mon, 1 Jul 2019 00:00:00 -0700" + "Mon, 1 Jul 2019 12:00:00 -0700" + "Sun, 1 Sep 2019 00:00:00 -0700" + } +} [ "0 0,12 1 */2 *" next-few-times ] unit-test + +! At 04:00 on every day-of-month from 8 through 14. +{ + { + "Mon, 8 Apr 2019 04:00:00 -0700" + "Tue, 9 Apr 2019 04:00:00 -0700" + "Wed, 10 Apr 2019 04:00:00 -0700" + "Thu, 11 Apr 2019 04:00:00 -0700" + "Fri, 12 Apr 2019 04:00:00 -0700" + } +} [ "0 4 8-14 * *" next-few-times ] unit-test + +! At 00:00 on day-of-month 1 and 15 and on Wednesday. +{ + { + "Wed, 27 Mar 2019 00:00:00 -0700" + "Mon, 1 Apr 2019 00:00:00 -0700" + "Wed, 3 Apr 2019 00:00:00 -0700" + "Wed, 10 Apr 2019 00:00:00 -0700" + "Mon, 15 Apr 2019 00:00:00 -0700" + } +} [ "0 0 1,15 * 3" next-few-times ] unit-test + +! At 00:00 on Sunday. +{ + { + "Sun, 24 Mar 2019 00:00:00 -0700" + "Sun, 31 Mar 2019 00:00:00 -0700" + "Sun, 7 Apr 2019 00:00:00 -0700" + "Sun, 14 Apr 2019 00:00:00 -0700" + "Sun, 21 Apr 2019 00:00:00 -0700" + } +} [ "@weekly" next-few-times ] unit-test diff --git a/extra/crontab/crontab.factor b/extra/crontab/crontab.factor index 5745b97a78..2ea27a821e 100644 --- a/extra/crontab/crontab.factor +++ b/extra/crontab/crontab.factor @@ -66,18 +66,23 @@ CONSTANT: aliases H{ timestamp 1 >>day 0 >>hour 0 >>minute month<< drop t ] if - timestamp day>> :> day - cronentry days>> [ day >= ] find nip - [ day - ] [ - timestamp days-in-month cronentry days>> first - - ] if* - timestamp day-of-week :> weekday cronentry days-of-week>> [ weekday >= ] find nip [ cronentry days-of-week>> first 7 + - ] unless* weekday - + ] unless* weekday - :> days-to-weekday - min [ + timestamp day>> :> day + cronentry days>> [ day >= ] find nip [ + cronentry days>> first timestamp days-in-month + + ] unless* day - :> days-to-day + + cronentry days-of-week>> T{ range f 0 7 1 } = + cronentry days>> T{ range f 1 31 1 } = 2array + { + { { f t } [ days-to-weekday ] } + { { t f } [ days-to-day ] } + [ drop days-to-weekday days-to-day min ] + } case [ timestamp 0 >>hour 0 >>minute swap +day 2drop t ] unless-zero