Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Invalid results when crossing DST transition #82

Closed
mateuszf opened this issue Mar 14, 2017 · 4 comments
Closed

Invalid results when crossing DST transition #82

mateuszf opened this issue Mar 14, 2017 · 4 comments

Comments

@mateuszf
Copy link

First of all thanks for fixing #35

Still, there are more issues with local time and DST transition.
CRON uses local system time on Linux machines and users expect cron masks to work using local system time. However there are problems with e.g. daily masks when crossing DST transition time.
In the simplest scenario I want to use hourly mask 0 * * * * and daily masks 0 0 * * * in local time and users expect them to just work in their local time.
Examples using: croniter 0.3.15, Python 3.5.2

import json, calendar, time, pytz
from datetime import datetime
from croniter import croniter

tz = pytz.timezone('Europe/Warsaw')
standard -> DST transition at 2017-03-26 01:59+1:00 -> 03:00+2:00
dt_day1 = tz.localize(datetime(2017, 3, 26))
print(dt_day1)                                            # 2017-03-26 00:00:00+01:00
print(croniter('0 0 * * *', dt_day1).get_next(datetime))  # 2017-03-27 01:00:00+02:00 - INVALID
dt_hour1 = tz.localize(datetime(2017, 3, 26, 1))
print(dt_hour1)                                            # 2017-03-26 01:00:00+01:00
print(croniter('0 * * * *', dt_hour1).get_next(datetime))  # 2017-03-26 03:00:00+02:00 - OK
DST-> standard transition at 2017-10-29 02:59+2:00 -> 02:00+1:00
dt_day1 = tz.localize(datetime(2017, 10, 29))
print(dt_day1)                                            # 2017-10-29 00:00:00+02:00
print(croniter('0 0 * * *', dt_day1).get_next(datetime))  # 2017-10-29 23:00:00+01:00 - INVALID
dt_hour1 = tz.localize(datetime(2017, 10, 29, 2), is_dst=True)
print(dt_hour1)                                            # 2017-10-29 02:00:00+02:00
print(croniter('0 * * * *', dt_hour1).get_next(datetime))  # 2017-10-29 02:00:00+01:00 - OK

The reason this gives invalid results is that croniter converts datetime to timestamp internally, does arithmetics and converts back to datetime. This way information about local time is lost at conversion point and this method gives bad results after converting back to local. The only way to do this work correctly with local time is to do the arithmetics on localized datetime object using timedeltas and tz.normalize(...) - to check if e.g. midnight is still midnight after post-arithmetics normalization.

@kiorky kiorky closed this as completed Mar 15, 2017
@kiorky kiorky reopened this Mar 15, 2017
@kiorky
Copy link
Collaborator

kiorky commented Mar 15, 2017

Making a test case to explain how to handle this, i ll post you the link

@kiorky
Copy link
Collaborator

kiorky commented Mar 15, 2017

There is a bug, well, more of what i call a non implementation of DST handling.
I will try to do something betteR.

@kiorky
Copy link
Collaborator

kiorky commented Mar 15, 2017

fixed!

@kiorky kiorky closed this as completed in 1c05bed Mar 15, 2017
@kiorky
Copy link
Collaborator

kiorky commented Mar 15, 2017

0.3.16 released on pypi

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants