|
1 | 1 | import time
|
2 |
| -from datetime import datetime, timezone |
| 2 | +import sys |
| 3 | +from datetime import tzinfo, datetime, timezone |
3 | 4 | from enum import Enum
|
4 | 5 | from typing import TYPE_CHECKING, Optional, Union
|
5 | 6 |
|
@@ -56,6 +57,9 @@ def fromisocalendar(cls, year: int, week: int, day: int) -> "Timestamp":
|
56 | 57 |
|
57 | 58 | @classmethod
|
58 | 59 | def fromtimestamp(cls, t: float, tz=None) -> "Timestamp":
|
| 60 | + if sys.platform == "win32" and t < 0: |
| 61 | + raise ValueError("Negative timestamps are not supported on Windows.") |
| 62 | + |
59 | 63 | try:
|
60 | 64 | timestamp = super().fromtimestamp(t, tz=tz)
|
61 | 65 | except Exception:
|
@@ -85,6 +89,28 @@ def utcnow(cls) -> "Timestamp":
|
85 | 89 | t = time.time()
|
86 | 90 | return cls.utcfromtimestamp(t)
|
87 | 91 |
|
| 92 | + def astimezone(self, tz: tzinfo | None = None) -> "Timestamp": |
| 93 | + # workaround of https://github.com/python/cpython/issues/107078 |
| 94 | + |
| 95 | + if sys.platform != "win32": |
| 96 | + return super().astimezone(tz) |
| 97 | + |
| 98 | + # this bound is loose, but it's good enough for our purposes |
| 99 | + if self.year > 1970 or (self.year == 1970 and (self.month > 1 or self.day > 1)): |
| 100 | + return super().astimezone(tz) |
| 101 | + |
| 102 | + if self.year < 1969 or self.month < 12 or self.day < 31: |
| 103 | + # windows kind of breaks down for dates before unix time |
| 104 | + # technically this is solvable, but it's not worth the effort |
| 105 | + # also, again, this is a loose bound, but it's good enough for our purposes |
| 106 | + raise ValueError("astimezone with no arguments is not supported for dates before Unix Time on Windows.") |
| 107 | + |
| 108 | + # to work around the issue to some extent, we'll use a timestamp with a date |
| 109 | + # that doesn't trigger the bug, and use the timezone from it to modify this |
| 110 | + # timestamp |
| 111 | + sample_datetime = Timestamp(1970, 1, 5).astimezone() |
| 112 | + return self.replace(tzinfo=sample_datetime.tzinfo) |
| 113 | + |
88 | 114 | def to_snowflake(self, high: bool = False) -> Union[str, "Snowflake"]:
|
89 | 115 | """
|
90 | 116 | Returns a numeric snowflake pretending to be created at the given date.
|
|
0 commit comments