Incorrect prev / next calculations around daylight savings time
When using a daylight-savings-time timezone like America/New_York, around the date of the daylight savings time change, the next/prev time is off by 1 hour.
In the example below, the cron expression says that it should run at 6am every day. But when you get the next times, on March 10, croniter says it will run at 5am and when you get the previous times, on March 9th, croniter says it will run at 7am. Note that the next times and the previous times don't even agree with each other.
Reproduction steps:
from datetime import datetime, timedelta
import itertools
from zoneinfo import ZoneInfo
from croniter import croniter
nytz = ZoneInfo("America/New_York")
dst_start = datetime(2024, 3, 10, 3, 0, tzinfo=nytz)
c = croniter("0 6 * * *", start_time=dst_start - timedelta(days=2), ret_type=datetime)
print("Nexts:")
for t in itertools.islice(c.all_next(), 5):
print(t)
c2 = croniter("0 6 * * *", start_time=dst_start + timedelta(days=2), ret_type=datetime)
print("Prevs:")
for t in itertools.islice(c2.all_prev(), 5):
print(t)
Output is:
Nexts:
2024-03-08 06:00:00-05:00
2024-03-09 06:00:00-05:00
2024-03-10 05:00:00-04:00
2024-03-10 06:00:00-04:00
2024-03-11 06:00:00-04:00
Prevs:
2024-03-11 06:00:00-04:00
2024-03-10 06:00:00-04:00
2024-03-09 07:00:00-05:00
2024-03-09 06:00:00-05:00
2024-03-08 06:00:00-05:00
Expected output should be:
Nexts:
2024-03-08 06:00:00-05:00
2024-03-09 06:00:00-05:00
2024-03-10 06:00:00-04:00
2024-03-10 06:00:00-04:00
2024-03-11 06:00:00-04:00
Prevs:
2024-03-11 06:00:00-04:00
2024-03-10 06:00:00-04:00
2024-03-09 06:00:00-05:00
2024-03-09 06:00:00-05:00
2024-03-08 06:00:00-05:00
I ran into this today as well. I also found that I don't have this problem if I use pytz instead of zoneinfo, e.g. in the example in the original post if I instead define nytz=pytz.timezone("America/New_York"), the outputs are as expected. But pytz is no longer supported, so using it is not a good workaround. I will try to find time to look into this more within the next few weeks.
I can confirm that. MWE:
from tzlocal import get_localzone
import datetime
from croniter.croniter import croniter
import zoneinfo
import pytz
tz = get_localzone()
assert tz == zoneinfo.ZoneInfo(key='Europe/Berlin')
#tz = pytz.timezone("Europe/Berlin") # <= this fixes it
start_time = datetime.datetime(2024,10,26,6,0).astimezone(tz)
ci = croniter('15 7 * * *', start_time=start_time)
assert ci.get_next(float) == 1729919700.0 # 2024-10-26T07:15:00+02:00
assert ci.get_next(float) == 1730009700.0 # 2024-10-27T07:15:00+01:00 !! <= this assertion fails without the pytz line above
duplicate #1