Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 7 additions & 10 deletions arrow/constants.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,24 @@
"""Constants used internally in arrow."""

import sys
from datetime import datetime
from datetime import datetime, timezone
from typing import Final

# datetime.max.timestamp() errors on Windows, so we must hardcode
# the highest possible datetime value that can output a timestamp.
# tl;dr platform-independent max timestamps are hard to form
# See: https://stackoverflow.com/q/46133223
# datetime.max.replace(tzinfo=timezone.utc).timestamp() gives the platform-independent
# max POSIX timestamp. Without tzinfo=timezone.utc, datetime.max.timestamp() raises
# OverflowError or ValueError ("year 10000 is out of range") in timezones ahead of UTC.
try:
# Get max timestamp. Works on POSIX-based systems like Linux and macOS,
# but will trigger an OverflowError, ValueError, or OSError on Windows
_MAX_TIMESTAMP = datetime.max.timestamp()
_MAX_TIMESTAMP = datetime.max.replace(tzinfo=timezone.utc).timestamp()
except (OverflowError, ValueError, OSError): # pragma: no cover
# Fallback for Windows and 32-bit systems if initial max timestamp call fails
# Must get max value of ctime on Windows based on architecture (x32 vs x64)
# https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/ctime-ctime32-ctime64-wctime-wctime32-wctime64
# Note: this may occur on both 32-bit Linux systems (issue #930) along with Windows systems
is_64bits = sys.maxsize > 2**32
_MAX_TIMESTAMP = (
datetime(3000, 1, 1, 23, 59, 59, 999999).timestamp()
datetime(3000, 1, 1, 23, 59, 59, 999999, tzinfo=timezone.utc).timestamp()
if is_64bits
else datetime(2038, 1, 1, 23, 59, 59, 999999).timestamp()
else datetime(2038, 1, 1, 23, 59, 59, 999999, tzinfo=timezone.utc).timestamp()
)

MAX_TIMESTAMP: Final[float] = _MAX_TIMESTAMP
Expand Down
4 changes: 4 additions & 0 deletions tests/test_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,10 @@ def test_normalize_timestamp(self):
assert util.normalize_timestamp(millisecond_timestamp) == 1591161115.194
assert util.normalize_timestamp(microsecond_timestamp) == 1591161115.194556

# Test timestamp for year 9999-12-31 is not mistakenly divided by 1000
max_year_ts = 253402214400.0
assert util.normalize_timestamp(max_year_ts) == max_year_ts

with pytest.raises(ValueError):
util.normalize_timestamp(3e17)

Expand Down
Loading