以下是使用Python解析crontab时间格式的一个类, 同时minute和hour支持了 + 的操作. 记录一下备忘.

其中的line参数是字符串分拆后的格式, 包含了 "week", "month", "day", "hour", "minute".

#!/usr/bin/env python3
# -*-coding:utf-8-*- """
支持crontab表达式的分解, 判断是否符合条件.
@author Felix Zhang
@contact cnscud@gmail.com
@since 2018.1.11
""" from datetime import datetime class MatchTimeExp(object):
TIMEUNIT_FORMAT = {"minute": "%M", "hour": "%H", "day": "%d", "month": "%m", "year": "%Y", "week": "%w"}
TIMEUNIT_SCALE = {"minute": 60, "hour": 24} @staticmethod
def fire(line, cur_time):
holders = ["week", "month", "day", "hour", "minute"]
for h in holders:
if line[h] is not None and line[h] != "":
ret = MatchTimeExp.matchtime(line[h], h, cur_time)
if ret != 0:
return ret return 0 @staticmethod
def matchtime(exp, timeunit, thetime):
"""支持的格式: * 5 */5 */5+2 1,2,3 5-22 5-8,11-15
@:type thetime datetime
@:return match=0 , not match =1 , error = -1
"""
assert isinstance(thetime, datetime) exp = exp.replace(" ", "") digit_exp = exp.replace(",", "").replace("-", "").replace("/", "").replace("*", "").replace("+", "")
if digit_exp != "" and not digit_exp.isdigit():
return -1 # 分解逗号
nodes = exp.split(",")
if len(nodes) > 1:
for node in nodes:
if node != "" and MatchTimeExp.__matchtime_one(node, timeunit, thetime) == 0:
return 0
return 1
else:
return MatchTimeExp.__matchtime_one(exp, timeunit, thetime) @staticmethod
def __check_plusexp(step, timeunit, curtimenode):
""" 支持+ 的特殊语法""" # 仅支持
if timeunit not in ("minute", "hour"):
return -1 parts = step.strip().split("+")
if len(parts) == 2 and parts[0].strip().isdigit() and parts[1].strip().isdigit():
mystep = int(parts[0])
plusvalue = int(parts[1])
if plusvalue >= mystep:
return -1 timenode = curtimenode - plusvalue
if timenode < 0:
timenode += MatchTimeExp.TIMEUNIT_SCALE.get(timeunit) if timenode % mystep == 0:
return 0
else:
return -1 return 1 @staticmethod
def __matchtime_one(exp, timeunit, thetime):
if exp == "*":
return 0 if exp == "" or exp is None:
return 1 curtimenode = int(thetime.strftime(MatchTimeExp.TIMEUNIT_FORMAT.get(timeunit))) if exp == str(curtimenode):
return 0 patternfind = False items = exp.split('/')
if len(items) == 2 and items[0] == "*":
patternfind = True
step = items[1]
if step.isdigit():
if curtimenode % int(step) == 0:
return 0
else:
return MatchTimeExp.__check_plusexp(step, timeunit, curtimenode)
elif len(items) > 1:
return -1 # # 逗号
# nodes = exp.split(",")
# if len(nodes) > 0:
# for node in nodes:
# if node.strip() == str(curtimenode):
# return 0 # 减号:表示范围
nodes = exp.split("-")
if len(nodes) > 1:
patternfind = True
if len(nodes) == 2 and nodes[0].strip().isdigit() and nodes[1].strip().isdigit():
if int(nodes[0].strip()) <= curtimenode <= int(nodes[1].strip()):
return 0
else:
return -1 if not patternfind and not exp.isdigit():
return -1 return 1 def main():
thetime = datetime.now()
thetime = thetime.replace(minute=5) # 测试分钟
test("*", thetime, 0)
test("*/5", thetime, 0)
test("*/3", thetime, 1)
test("5", thetime, 0)
test("6", thetime, 1)
test("5,10,15", thetime, 0)
test("2,4,6", thetime, 1)
test("2-6", thetime, 0)
test("12-25", thetime, 1) test("2-6,9-12", thetime, 0)
test("12-15, 20-23", thetime, 1) thetime = datetime.now()
thetime = thetime.replace(minute=15)
test("*/5", thetime, 0)
test("*/3", thetime, 0)
test("*/7", thetime, 1)
test("6", thetime, 1)
test("5,10,15", thetime, 0)
test("2-6", thetime, 1)
test("12-25", thetime, 0)
test("2-6,9-12", thetime, 1)
test("12-15, 20-23", thetime, 0) thetime = datetime.now()
thetime = thetime.replace(minute=5)
test("*/7+6", thetime, 1)
test("*/7+5", thetime, 0)
test("*/7+2", thetime, 1) thetime = datetime.now()
thetime = thetime.replace(minute=1)
test("*/7+6", thetime, 1)
test("*/7+5", thetime, 0)
test("*/7+2", thetime, 1) thetime = datetime.now()
thetime = thetime.replace(minute=12)
test("*/7+5", thetime, 0)
test("*/7+1", thetime, 1)
test("*/7+9", thetime, -1) # wrong exp
test("a-b", thetime, -1)
test("a,2", thetime, -1)
test("*/b", thetime, -1)
test("*/7+a", thetime, -1)
test("*/a+b", thetime, -1) # , + - / * thetime = datetime.now()
thetime = thetime.replace(minute=12) test("12,", thetime, 0)
test("11,", thetime, 1)
test(",2", thetime, 1) test("3-5-8", thetime, -1)
test("3-", thetime, -1)
test("-3", thetime, -1)
test("5+2", thetime, -1)
test("/2", thetime, -1)
test("2/", thetime, -1)
test("*5", thetime, -1) thetime = datetime.now()
thetime = thetime.replace(hour=8) test("*/3+2", thetime, 0, "hour")
test("*/3+1", thetime, 1, "hour")
test("*/3+5", thetime, -1, "hour") thetime = thetime.replace(hour=1) test("*/3+2", thetime, 1, "hour")
test("*/3+1", thetime, 0, "hour") thetime = thetime.replace(day=5) test("*/4", thetime, 1, "day")
test("*/5", thetime, 0, "day")
test("*/3+2", thetime, -1, "day") thetime = datetime.now()
thetime = thetime.replace(minute=6) test_all({"week": "*", "month": "*", "day": "*", "hour": "*", "minute": "*/3"}, thetime, 0)
test_all({"week": "*", "month": "*", "day": "*", "hour": "*", "minute": "*/4"}, thetime, 1) def test_all(line, curtime, okresult):
timeprint = curtime.strftime("%Y-%m-%d %H:%M:%S")
# minute hour day month week
lineprint = " ".join([line["minute"], line["hour"], line["day"], line["month"], line["week"]])
if MatchTimeExp.fire(line, curtime) == okresult:
print("pass: matchtime %s check: (%s) is %i in %s" % ("all", lineprint, okresult, timeprint))
else:
print("not pass: matchtime %s check (%s) is %i in %s" % ("all", lineprint, okresult, timeprint)) def test(exp, curtime, okresult, unit="minute"):
timeprint = curtime.strftime("%Y-%m-%d %H:%M:%S")
if MatchTimeExp.matchtime(exp, unit, curtime) == okresult:
print("pass: matchtime %s check %s is in %s" % (unit, exp, timeprint))
else:
print("not pass: matchtime %s check %s is in %s" % (unit, exp, timeprint)) if __name__ == '__main__':
main()

Python: 解析crontab正则,增加+操作的更多相关文章

  1. Python学习-列表的转换和增加操作

    列表的转换和增加操作 列表的转换操作:可以将一个元组,字符串等转换成列表. str = "liuwenhao"; print(list(str)); // ['l', 'i', ' ...

  2. python 解析json loads dumps

    认识 引用模块 重要函数 案例 排序 缩进参数 压缩 参考 认识 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.它基于JavaScript(Standa ...

  3. Python解析器源码加密系列之(二):一次使用标准c的FILE*访问内存块的尝试

    摘要:由于近期打算修改Python解释器以实现pyc文件的加密/解密,出于保密的要求,解密之后的数据只能放在内存中,不能写入到文件中.但是后续的解析pyc文件的代码又只能接受FILE*作为入参,所以就 ...

  4. python 解析json

    一.概念 序列化(Serialization):将对象的状态信息转换为可以存储或可以通过网络传输的过程,传输的格式可以是JSON.XML等.反序列化就是从存储区域(JSON,XML)读取反序列化对象的 ...

  5. python解析xml之lxml

    虽然python解析xml的库很多,但是,由于lxml在底层是用C语言实现的,所以lxml在速度上有明显优势.除了速度上的优势,lxml在使用方面,易用性也非常好.这里将以下面的xml数据为例,介绍l ...

  6. dom4j解析XML的CURD操作

    在开发JavaWeb项目中通常是利用XML配置文件来提高应用程序的访问效率,而在配置XML的同时,更多时候是对XML进行解析. 一.解析XML配置文件有两种机制: DOM和SAX的机制: DOM是将整 ...

  7. python 解析Excel

    python 解析Excel 公司背景:好吧LZ太懒了.略... 原由起因:公司老板发话要导出公司数据库中符合条件的数据,源数据有400万,符合条件的大概有70万左右吧. 最终目的:符合条件的数据并生 ...

  8. Python 解析构建数据大杂烩 -- csv、xml、json、excel

    Python 可以通过各种库去解析我们常见的数据.其中 csv 文件以纯文本形式存储表格数据,以某字符作为分隔值,通常为逗号:xml 可拓展标记语言,很像超文本标记语言 Html ,但主要对文档和数据 ...

  9. python入门学习:3.操作列表

    python入门学习:3.操作列表 关键点:列表 3.1 遍历整个列表3.2 创建数值列表3.3 使用列表3.4 元组 3.1 遍历整个列表   循环这种概念很重要,因为它是计算机自动完成重复工作的常 ...

随机推荐

  1. 谈谈fork/join实现原理

    害,又是一个炒冷饭的时间.fork/join是在jdk1.7中出现的一个并发工作包,其特点是可以将一个大的任务拆分成多个子任务进行并行处理,最后将子任务结果合并成最后的计算结果,并进行输出.从而达到多 ...

  2. springboot+kurento+coturn+contos的视频通讯服务搭建

    springboot+kurento+coturn+contos的视频通讯服务搭建 服务器CentOS Linux release 7.9.2009 (Core) 本案例成功于20210628 1.默 ...

  3. Linux 安装及管理程序

    Linux 安装及管理程序 目录 一.Linux应用程序基础 1.1.应用程序与系统命令的关系 1.2.典型应用程序的目录结构 1.2.常见的软件包封装类型 二.RPM包管理工具 2.1.RPM软件包 ...

  4. Golang修改操作系统时间

    Golang修改操作系统时间 需求 程序有时需要和服务器对时,发现延迟过高修改本地时间,这段代码网上抄的,实测可用,windows环境需要以管理员身份启动命令提示符调试 实现Demo package ...

  5. Linux中mail的用法

    简介:mail命令是命令行的电子邮件发送和接收工具.操作的界面不像elm或pine那么容易使用,但功能非常完整Red Hat上sendmail服务一般是自动启动的.可以通过下面的命令查看sendmai ...

  6. 12-1 MySQL数据库备份(分库)

    #!/bin/bash source /etc/profile DATE="$(date +%F_%H-%M-%S)" DB_IP="172.16.1.122" ...

  7. hadoop安装前的准备

    1.操作系统安装 2.hostname设定 3.hosts文件设定 4.ssh免密码登录 5.NTP时间同步设定 6.iptables永久关闭 7.selinux永久关闭

  8. 4shell中的特殊变量

    1.位置参数 2.其他特殊变量 2.1 用法举栗 2.2 $* 和 $@ 的区别 2.3 $?的用法 1.位置参数 运行 Shell 脚本文件时我们可以给它传递一些参数,这些参数在脚本文件内部可以使用 ...

  9. 扩大UIPageViewController的点击范围

    UIPageViewController中的边缘点击手势大概是屏幕的1/6,市面的大多数阅读器点击手势都在1/3以上,或者我干脆想自定义点击的范围,但又不想放弃系统的翻页效果,这时候该怎么做了?其实很 ...

  10. create-react-app 入门学习

    全局安装 create-react-app npm install create-react-app -g 创建项目 在全局安装了create-react-app 后 创建项目,如果按照下面的第一种办 ...