Skip to content
Branch: master
Find file History
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
..
Failed to load latest commit information.
src
README.md
pom.xml

README.md

NutzCron : 定期运行的表达式

通过一个字符串,可以描述一系列时间点,以便程序定期启动,这件事 Quartz Cron 表达式已经做的不错了。它已经极强的扩展了 Linux Cron 的能力。

但是,还不够。譬如有一个比较常用的场景:

从今年下个月15号开始,每天的 8:00,10:30,14:40 各运行一次

为此,我定义了 NutzCron,它扩展了 Quartz Cron 的语法,以便能适用更多的场景。

这个代码库提供了什么

本代码库并不负责任务的定期支持,本代码库仅仅为你提供对 NutzCron 解析和解释和执行的能力。

所谓解析

诚然,就是你给我一个字符串,我给你解析成一个类 ZCron

所谓解释

ZCron 类有一个函数 toText 接受一个 i18n 的消息字符串模板集,它会把当前的设定根据你给的消息模板集,转成一个人类比较容易看懂的文字。本文后面章节会专门介绍这个消息模板集怎么设置。总之不太复杂啦,就是一个普通的JSON对象

所谓执行

对于一个 ZCron 对象,怎么执行呢?因为这是一个轻巧的解析库,我认为你只是需要通过这个表达式拿到一系列启动时间点。后面的事情,你也不需要我来关心。

那么我怎么给你一系列启动时间点呢?返回一个列表吗?不不不,我通常不会这么设计的,因为我觉得有点不够优雅(为啥不优雅?呃,我就认为不优雅,你咬我啊!!!)。

我这里的 执行 实际上是 填充

即,你需要提供给我一个数组,对,你没看错,是一个数组。由于表达式的时间最多精确到秒,所以你给我的数组,最大长度不应该超过86400,即,一秒对应一个数组元素。

然后,你再给我一个对象,随便什么对象,我会把这个对象填到对应的数组格子里

@Str  : `0 0 0 * * ?`    <- 输入表达式
@Obj  : ?                <- 输入一个随便什么对象
@Arr  : [ ][ ]..[ ][ ]   <- 输入一个数组,通常是空白数组
@Date : 2017..           <- 输出一个日期

// 解析并执行
js:    ZCron(@Str).fill(@Arr, @Obj, @Date)
java:  new ZCron(@Str).fill(@Arr, @Obj, @Date)

// 你输入的 @Arr 会变成
[ ][ ][ ][Obj][ ]...[ ][Obj][ ][ ][ ]

那么通过遍历数组,你自然知道启动的时间了。

那么你可能会问,每次都要给你86400这么长的空数组吗?不用的,你其实可以给我譬如24长的数组,表示[00:00][01:00]..[22:00][23:00]这24个时间点,如果任何一个时间点被表达式匹配,我就会填充对象。

这也就是我让你输入数组的好处,你可以通过改变数组的长度,将每天分成固定等份。譬如你给我48长度的数组,则表示[00:00][00:30][01:00][01:30]..[23:00][23:30] 这48个时间点。

表达式语法

下面我们来正式说说,这个表达式的语法。我先给你一个例子

0 0 0 * * ? 

熟悉 quartz 的朋友马上会发现,这不就是 Quartz 嘛。 是的,表达式完全兼容 Quartz 表达式。

表达式的信息分作两部分

  1. 描述一天的时间点
  2. 限制日期

考虑到有的朋友对 Quartz 不熟,我这里先把 Quzrtz 的语法贴一下,NutzCron 完全兼容哦。

Quartz 语法的简要说明

官方语法说明看这里

表达式是一个字符串,它有六个子表达式构成。这些子表达式用空格来分隔。 
# 子表达式描述如下: 
0) 秒(0~59) 
1) 分钟(0~59) 
2) 小时(0~23) 
3) 天(月)(1~31,但是你需要考虑你月的天数) 
4) 月(1~12) 
5) 周(星期)(1~7 1=SUN 或 SUN,MON,TUE,WED,THU,FRI,SAT)
6) 年 空 或 1970-2099,
# 特殊符号
'-' : 范围, 比如在子表达式(月),"1-4" 表示 2月到5月
"," : 列表分隔, 比如在子表达式(天-星期),"1,3" 表示 周日和周二
"*" : 代表所有可能的值
"/" : 用来指定数值的增量
       > 例如: 在子表达式(分钟)里的 "0/15" 表示从第0分钟开始,每15分钟
       > 又如: 在子表达式(分钟)里的 "3/20" 表示从第3分钟开始,每20分钟
              (它和 "3,23,43" )的含义一样 
"?" : 仅被用于天(月)和天(星期)两个子表达式,表示不指定值 
"L" : 仅被用于天(月)和天(星期)两个子表达式,它是单词“last”的缩写
       > 在天(月)子表达式中,“L”表示一个月的最后一天
           >> 6L”表示这个月的倒数第6天
       > 在天(星期)自表达式中,“L”表示一个星期的最后一天,也就是SAT
           >> “FRIL”表示这个月的最一个星期五
"W" : 仅被用于天(月)子表达式,表示工作日
       > "W" 为所有工作日
       > "4W" 为距离本月第5日最近的工作日
       > "4LW" 为距离当月倒数第4日最近的工作日
"#" : 仅用在天(星期)表示第几个
       > 3#1 表示 第1个周二
       > FRI#2 第2个周五

譬如*(ZCron.toText 自动生成)*:

0 0 0 * * ?            : 每月的每天的0点0分0秒
0 0 ? * * ?            : 每月的每天的每小时的0分0秒
0 ? ? * * ?            : 每月的每天的每小时的每分钟的0秒
0 0 8-11,13-18 * * ?   : 每月的每天的8点至11点,13点至18点0分0秒
0 0 0 7-13 JUL ?       : 七月的7号至13号的0点0分0秒
0 0 0 1,3,5 * ?        : 每月的1号,3号,5号的0点0分0秒
0 0 8/3 * * ?          : 每月的每天的从8点开始每3小时0分0秒
0 0 0 4L * ?           : 每月的倒数第4日的0点0分0秒
0 0 0 W * ?            : 每月的所有工作日的0点0分0秒
0 0 0 1LW * ?          : 每月的最后一日最近的工作日的0点0分0秒
0 0 0 6LW * ?          : 每月的倒数第6日最近的工作日的0点0分0秒
0 0 0 * * 1-3          : 每月的周日至周二的每天0点0分0秒
0 0 0 * * 1,2-4,7      : 每月的周日,周一至周三,周六的每天0点0分0秒
0 0 0 * * FRI#2        : 每月的第2个周五的每天0点0分0秒
0 0 0 * * 2#4          : 每月的第4个周一的每天0点0分0秒
0 0/5 8,10-14,23 * * ? : 每月的每天的8点,10点至14点,23点从0分开始每5分钟0秒
0 0 0,1 * * ?          : 每月的每天的0点,1点0分0秒

ZCron 扩展语法

(扩展部分) (Quartz的时间部分) (Quartz的日期部分) (扩展部分)
   ...      0    0    0      *    *    ?       ...

即,你可以在标准 Quartz 表达式前面或者后面增加扩展部分,它的语法具体为:

D[20170801,20170822)   # D 开头限定日期区间(不能包括空格)
T[08:12,09:16]         # T 开头限定时间区间(不能包括空格)
                       # 这个会结合 Quartz 的时间部分来确定启动时间点
T[08:12,09:16]{0/30m}  # 在时间限定区间后面跟上 {offset/step} 表示一组时间点
                       # 譬如这个 0/30m 表示:
                       # 循环开始偏移量 0 表示从区间开始处开始
                       # 循环间隔30分钟,支持的单位为 s秒,m分,h小时
                       # 循环开始偏移量还是可以是:
                       #  "10s"  : 从区间开始时间偏移 10 秒
                       #  "8m"   : 从区间开始时间偏移 8 分钟
                       #  "2h"   : 从区间开始时间偏移 2 小时
                       #  ">"    : 以循环间隔为单位将全天均分,偏移至最近的一个时间点
                       #  ">24m" : 以24分钟为单位将全天均分,偏移至最近的一个时间点
                       #           因此 -/30m 与 -30m/30m 的意义是一样的
                       #  ">2h"  : 2小时全天均分
                       #  ">50s" : 50秒全天均分
                       #  "2"    : 根据循环间隔的时间单位一致
                       # ! 如果声明了这个那么 Quartz 的时间部分会被无视,
                       # 你可以不写,写了也没用
T{02:30,06:48,18:25}   # T{..} 格式的为明确指定自由的启动时间点(不能包括空格)
                       # ! 如果声明了这个那么 Quartz 的时间部分会被无视,
                       # 你可以不写,写了也没用

------------------------------------------------
> 注意哦,T,D 开头的,后面跟着是区间表达式,中学数学学的区间没忘吧。开区间闭区间。
> 总之,`[` 表示闭,`(` 表示开

[34,100] 表示 n>=34 && n<=100
(34,100] 表示 n>34 && n<=100
[34,100) 表示 n>=34 && n<100
[34,]    表示 n>=34
[34,)    表示 n>=34
(34,]    表示 n>34
(34,)    表示 n>34
[,100]   表示 n<=100
(,100]   表示 n<=100
[,100)   表示 n<100
(,100)   表示 n<100
(100)    表示 n!=100
[100]    表示 n==100
(100]    表示 n==100
[100)    表示 n==100
You can’t perform that action at this time.