@@ -79,15 +79,34 @@ def verify_success_with_redirection_for_multi_devices(status: TSStatus, devices:
7979
8080def convert_to_timestamp (time : int , precision : str , timezone : str ):
8181 try :
82- return pd .Timestamp (time , unit = precision , tz = timezone )
82+ ts = pd .Timestamp (time , unit = precision , tz = timezone )
8383 except OutOfBoundsDatetime :
84- return pd .Timestamp (time , unit = precision ).tz_localize (timezone )
84+ try :
85+ ts = pd .Timestamp (time , unit = precision ).tz_localize (timezone )
86+ except NotImplementedError :
87+ return pd .Timestamp (time , unit = precision )
8588 except ValueError :
8689 logger .warning (
8790 f"Timezone string '{ timezone } ' cannot be recognized by pandas. "
8891 f"Falling back to local timezone: '{ get_localzone_name ()} '."
8992 )
90- return pd .Timestamp (time , unit = precision , tz = get_localzone_name ())
93+ ts = pd .Timestamp (time , unit = precision , tz = get_localzone_name ())
94+ except NotImplementedError :
95+ # Timestamp falls outside Python's stdlib datetime range (year < 1 or
96+ # > 9999). pandas >= 3.0 cannot attach a timezone to such Timestamps
97+ # because tz conversion relies on toordinal(). Return naive instead.
98+ return pd .Timestamp (time , unit = precision )
99+ # Construction succeeded but utcoffset() may still fail downstream (e.g.
100+ # in pd.DataFrame's tz alignment) when the Timestamp's year is outside
101+ # 1..9999 and tz is not the canonical UTC. Probe early and fall back to
102+ # naive so callers like result_set_to_pandas() don't blow up. NaT does
103+ # not need this check (and does not support utcoffset()).
104+ if ts is not pd .NaT :
105+ try :
106+ ts .utcoffset ()
107+ except NotImplementedError :
108+ return pd .Timestamp (time , unit = precision )
109+ return ts
91110
92111
93112unit_map = {
@@ -108,3 +127,34 @@ def isoformat(ts: pd.Timestamp, unit: str):
108127 f"Falling back to use auto timespec'."
109128 )
110129 return ts .isoformat ()
130+ except NotImplementedError :
131+ # Timestamp falls outside Python's stdlib datetime range. pandas >= 3.0
132+ # routes isoformat through datetime.isoformat, which calls toordinal()
133+ # and fails. Build the ISO 8601 string from individual components.
134+ return _isoformat_from_components (ts , unit )
135+
136+
137+ def _isoformat_from_components (ts : pd .Timestamp , unit : str ) -> str :
138+ base = (
139+ f"{ ts .year :04d} -{ ts .month :02d} -{ ts .day :02d} "
140+ f"T{ ts .hour :02d} :{ ts .minute :02d} :{ ts .second :02d} "
141+ )
142+ if unit == "ms" :
143+ base += f".{ ts .microsecond // 1000 :03d} "
144+ elif unit == "us" :
145+ base += f".{ ts .microsecond :06d} "
146+ elif unit == "ns" :
147+ base += f".{ ts .microsecond :06d} { ts .nanosecond :03d} "
148+ if ts .tzinfo is not None :
149+ try :
150+ offset = ts .utcoffset ()
151+ except NotImplementedError :
152+ # utcoffset() needs toordinal() for zones like Etc/UTC. Omit offset.
153+ offset = None
154+ if offset is not None :
155+ total_seconds = int (offset .total_seconds ())
156+ sign = "+" if total_seconds >= 0 else "-"
157+ total_seconds = abs (total_seconds )
158+ hh , mm = divmod (total_seconds // 60 , 60 )
159+ base += f"{ sign } { hh :02d} :{ mm :02d} "
160+ return base
0 commit comments