From 5017657ca991812b7fcbbefead536cd7836ee576 Mon Sep 17 00:00:00 2001 From: TianZhen Date: Fri, 2 Jun 2017 15:59:00 +0800 Subject: [PATCH 1/2] feat: crontab expression for schedule --- .gitignore | 2 ++ requirements.txt | 1 + setup.py | 3 ++- tasktiger/schedule.py | 6 +++++- 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index e403a912..c4f37115 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ build/ dist/ *.egg-info/ .tox/ +.env/ +.idea/ \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 03b67a06..c526b410 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ click==4.0 redis==2.10.5 structlog==15.1.0 +croniter==0.3.17 \ No newline at end of file diff --git a/setup.py b/setup.py index bed79906..da0c5540 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,8 @@ install_requires = [ 'click', 'redis', - 'structlog' + 'structlog', + 'croniter' ] tests_require = install_requires + [ diff --git a/tasktiger/schedule.py b/tasktiger/schedule.py index 4ef44fdf..45438bf6 100644 --- a/tasktiger/schedule.py +++ b/tasktiger/schedule.py @@ -1,6 +1,7 @@ import datetime +import croniter -__all__ = ['periodic'] +__all__ = ['periodic', 'cron_expr'] def _periodic(dt, period, start_date, end_date): if end_date and dt >= end_date: @@ -39,3 +40,6 @@ def periodic(seconds=0, minutes=0, hours=0, days=0, weeks=0, start_date=None, # Saturday at midnight start_date = datetime.datetime(2000, 1, 1) return (_periodic, (period, start_date, end_date)) + +def cron_expr(expr_format): + return lambda dt, expr: croniter.croniter(expr, start_time=dt).get_next(ret_type=datetime.datetime), (expr_format, ) \ No newline at end of file From 95a0293f179733188711f11cadc4c1f9b2c6ab67 Mon Sep 17 00:00:00 2001 From: TianZhen Date: Thu, 8 Jun 2017 10:50:26 +0800 Subject: [PATCH 2/2] fix: cron_expr convert utc dt to local dt get next execution local dt convert local dt to utc dt --- setup.py | 4 +++- tasktiger/schedule.py | 14 +++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index da0c5540..d6e40a5a 100644 --- a/setup.py +++ b/setup.py @@ -4,7 +4,9 @@ 'click', 'redis', 'structlog', - 'croniter' + 'croniter', + 'pytz', + 'tzlocal', ] tests_require = install_requires + [ diff --git a/tasktiger/schedule.py b/tasktiger/schedule.py index 45438bf6..39f46af1 100644 --- a/tasktiger/schedule.py +++ b/tasktiger/schedule.py @@ -1,4 +1,6 @@ import datetime +import pytz +import tzlocal import croniter __all__ = ['periodic', 'cron_expr'] @@ -41,5 +43,15 @@ def periodic(seconds=0, minutes=0, hours=0, days=0, weeks=0, start_date=None, start_date = datetime.datetime(2000, 1, 1) return (_periodic, (period, start_date, end_date)) +def _cron_expr(naive_utc_dt, expr): + aware_utc_dt = pytz.utc.localize(naive_utc_dt) + local_timezone = tzlocal.get_localzone() + local_dt = aware_utc_dt.astimezone(local_timezone) + local_dt = local_timezone.normalize(local_dt) + next_dt = croniter.croniter(expr, start_time=local_dt).get_next(ret_type=datetime.datetime) + next_utc = next_dt.astimezone(pytz.utc) + next_utc = pytz.utc.normalize(next_utc) + return next_utc + def cron_expr(expr_format): - return lambda dt, expr: croniter.croniter(expr, start_time=dt).get_next(ret_type=datetime.datetime), (expr_format, ) \ No newline at end of file + return _cron_expr, (expr_format, )