Skip to content

Commit

Permalink
Fix overflow error on 32bit systems
Browse files Browse the repository at this point in the history
This fixes #87.
  • Loading branch information
kiorky committed Jul 26, 2024
1 parent f75df16 commit 5ee58de
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 2 deletions.
1 change: 1 addition & 0 deletions src/croniter/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from __future__ import absolute_import
from .croniter import (
croniter,
OVERFLOW32B_MODE,
datetime_to_timestamp,
croniter_range,
CroniterBadTypeRangeError, # noqa
Expand Down
15 changes: 14 additions & 1 deletion src/croniter/croniter.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@
# python2, just test that it's well installed
import pytz # noqa

EPOCH = datetime.datetime.fromtimestamp(0)
try:
# https://github.com/python/cpython/issues/101069 detection
datetime.datetime.fromtimestamp(3999999999)
OVERFLOW32B_MODE = False
except OverflowError:
OVERFLOW32B_MODE = True

try:
from collections import OrderedDict
except ImportError:
Expand Down Expand Up @@ -274,7 +282,12 @@ def _timestamp_to_datetime(self, timestamp):
"""
Converts a UNIX timestamp `timestamp` into a `datetime` object.
"""
result = datetime.datetime.fromtimestamp(timestamp, tz=tzutc()).replace(tzinfo=None)
if OVERFLOW32B_MODE:
# degraded mode to workaround Y2038
# see https://github.com/python/cpython/issues/101069
result = EPOCH + datetime.timedelta(seconds=timestamp)
else:
result = datetime.datetime.fromtimestamp(timestamp, tz=tzutc()).replace(tzinfo=None)
if self.tzinfo:
result = result.replace(tzinfo=tzutc()).astimezone(self.tzinfo)

Expand Down
10 changes: 9 additions & 1 deletion src/croniter/tests/test_croniter.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import pytz
from croniter.croniter import VALID_LEN_EXPRESSION
from croniter import (croniter, CroniterBadDateError, CroniterBadCronError, datetime_to_timestamp,
CroniterNotAlphaError, CroniterUnsupportedSyntaxError)
CroniterNotAlphaError, CroniterUnsupportedSyntaxError, OVERFLOW32B_MODE)
from croniter.tests import base
import dateutil.tz

Expand Down Expand Up @@ -1962,6 +1962,14 @@ def test_get_next_update_current(self):
self.assertEqual(uretp, uretap)
self.assertEqual(uretn, uretan)

def test_issue_2038y(self):
base = datetime(2040, 1, 1, 0, 0)
itr = croniter('* * * * *', base)
try:
itr.get_next()
except OverflowError:
raise Exception("overflow not fixed!")


if __name__ == '__main__':
unittest.main()

0 comments on commit 5ee58de

Please sign in to comment.