From ee145a1e77a9e29a8ece6ac70a788fc13949d391 Mon Sep 17 00:00:00 2001 From: SAY-5 Date: Sat, 23 May 2026 02:58:49 -0700 Subject: [PATCH] fix: preserve negative timezone offsets when cloning gpx Signed-off-by: SAY-5 --- gpxpy/gpxfield.py | 4 +++- test.py | 12 ++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/gpxpy/gpxfield.py b/gpxpy/gpxfield.py index e253df31..716b3e2c 100644 --- a/gpxpy/gpxfield.py +++ b/gpxpy/gpxfield.py @@ -63,7 +63,9 @@ def dst(self, dt: Optional[mod_datetime.datetime]) -> mod_datetime.timedelta: def tzname(self, dt: Optional[mod_datetime.datetime]) -> str: if self.offset == 0: return 'Z' - return f'{self.offset // 60:02}:{self.offset % 60:02}' + sign = '-' if self.offset < 0 else '+' + offset = abs(self.offset) + return f'{sign}{offset // 60:02}:{offset % 60:02}' def __copy__(self) -> mod_datetime.tzinfo: return self.__deepcopy__() diff --git a/test.py b/test.py index 7dd6f446..faabc32e 100644 --- a/test.py +++ b/test.py @@ -3127,6 +3127,18 @@ def test_timezone_from_timestamp(self) -> None: self.assertTrue(t_stamp + "+01:00" in reparsed.to_xml() or t_stamp + "+0100" in reparsed.to_xml()) self.assertTrue(reparsed.tracks[0].segments[0].points[0].time.tzinfo) # type: ignore + def test_deepcopy_negative_simpletz(self) -> None: + xml = '\n' + xml += '\n\n\n' + xml += '\n' + xml += '\n' + gpx = mod_gpxpy.parse(xml) + clone = gpx.clone() + original_time = gpx.tracks[0].segments[0].points[0].time + cloned_time = clone.tracks[0].segments[0].points[0].time + self.assertEqual(original_time, cloned_time) + self.assertEqual(cloned_time.utcoffset(), mod_datetime.timedelta(hours=-6)) # type: ignore + def test_timestamp_with_single_digits(self) -> None: xml = '\n' xml += '\n'