From c6c781768635795f4a958bb1381ad4b4a222b1ed Mon Sep 17 00:00:00 2001 From: Andrene Date: Thu, 1 Jan 2026 14:02:46 -0500 Subject: [PATCH 1/6] Fix utcfromtimestamp deprecation in resources file --- sc2reader/resources.py | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/sc2reader/resources.py b/sc2reader/resources.py index 7bb3b9a..2799de5 100644 --- a/sc2reader/resources.py +++ b/sc2reader/resources.py @@ -411,7 +411,10 @@ def load_details(self): self.windows_timestamp = details["file_time"] self.unix_timestamp = utils.windows_to_unix(self.windows_timestamp) - self.end_time = datetime.utcfromtimestamp(self.unix_timestamp) + self.end_time = datetime.fromtimestamp( + self.unix_timestamp, + datetime.UTC + ) # The utc_adjustment is either the adjusted windows timestamp OR # the value required to get the adjusted timestamp. We know the upper @@ -429,8 +432,9 @@ def load_details(self): seconds=self.length.seconds // GAME_SPEED_FACTOR[self.expansion].get(self.speed, 1.0) ) - self.start_time = datetime.utcfromtimestamp( - self.unix_timestamp - self.real_length.seconds + self.start_time = datetime.fromtimestamp( + self.unix_timestamp - self.real_length.seconds, + datetime.UTC ) self.date = self.end_time # backwards compatibility @@ -1088,7 +1092,10 @@ def __init__(self, summary_file, filename=None, lang="enUS", **options): else: self.expansion = "" - self.end_time = datetime.utcfromtimestamp(self.parts[0][8]) + self.end_time = datetime.fromtimestamp( + self.parts[0][8], + datetime.UTC + ) self.game_speed = LOBBY_PROPERTIES[0xBB8][1][self.parts[0][0][1].decode("utf8")] self.game_length = utils.Length(seconds=self.parts[0][7]) self.real_length = utils.Length( @@ -1096,8 +1103,9 @@ def __init__(self, summary_file, filename=None, lang="enUS", **options): self.parts[0][7] / GAME_SPEED_FACTOR[self.expansion][self.game_speed] ) ) - self.start_time = datetime.utcfromtimestamp( - self.parts[0][8] - self.real_length.seconds + self.start_time = datetime.fromtimestamp( + self.parts[0][8] - self.real_length.seconds, + datetime.UTC ) self.load_map_info() From 016efea331553ed8fbd6ea92e6e554f97b2af808 Mon Sep 17 00:00:00 2001 From: Andrene Date: Thu, 1 Jan 2026 14:05:35 -0500 Subject: [PATCH 2/6] Fix deprecation for utcfromtimestamp in gameheart plugin --- sc2reader/engine/plugins/gameheart.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sc2reader/engine/plugins/gameheart.py b/sc2reader/engine/plugins/gameheart.py index f2af2e8..9b72953 100644 --- a/sc2reader/engine/plugins/gameheart.py +++ b/sc2reader/engine/plugins/gameheart.py @@ -1,4 +1,4 @@ -from datetime import datetime +from datetime import datetime, timezone from sc2reader.utils import Length, get_real_type from sc2reader.objects import Observer, Team from sc2reader.engine.events import PluginExit @@ -65,8 +65,9 @@ def handleInitGame(self, event, replay): replay.real_length = Length( seconds=int(replay.game_length.seconds / GAME_SPEED_FACTOR[replay.speed]) ) - replay.start_time = datetime.utcfromtimestamp( - replay.unix_timestamp - replay.real_length.seconds + replay.start_time = datetime.fromtimestamp( + replay.unix_timestamp - replay.real_length.seconds, + timezone.UTC ) def fix_events(self, replay, start_frame): From c8191de9c921567cf17b39351bc7be8d6b0ccd75 Mon Sep 17 00:00:00 2001 From: Andrene Date: Thu, 1 Jan 2026 14:06:32 -0500 Subject: [PATCH 3/6] fix reference to utc. --- sc2reader/resources.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sc2reader/resources.py b/sc2reader/resources.py index 2799de5..0eaf759 100644 --- a/sc2reader/resources.py +++ b/sc2reader/resources.py @@ -1,5 +1,5 @@ from collections import defaultdict, namedtuple -from datetime import datetime +from datetime import datetime, timezone import hashlib from xml.etree import ElementTree import zlib @@ -413,7 +413,7 @@ def load_details(self): self.unix_timestamp = utils.windows_to_unix(self.windows_timestamp) self.end_time = datetime.fromtimestamp( self.unix_timestamp, - datetime.UTC + timezone.utc ) # The utc_adjustment is either the adjusted windows timestamp OR @@ -434,7 +434,7 @@ def load_details(self): ) self.start_time = datetime.fromtimestamp( self.unix_timestamp - self.real_length.seconds, - datetime.UTC + timezone.utc ) self.date = self.end_time # backwards compatibility @@ -1094,7 +1094,7 @@ def __init__(self, summary_file, filename=None, lang="enUS", **options): self.end_time = datetime.fromtimestamp( self.parts[0][8], - datetime.UTC + timezone.utc ) self.game_speed = LOBBY_PROPERTIES[0xBB8][1][self.parts[0][0][1].decode("utf8")] self.game_length = utils.Length(seconds=self.parts[0][7]) @@ -1105,7 +1105,7 @@ def __init__(self, summary_file, filename=None, lang="enUS", **options): ) self.start_time = datetime.fromtimestamp( self.parts[0][8] - self.real_length.seconds, - datetime.UTC + timezone.utc ) self.load_map_info() From c7728868cd8c4749ce9b8709ca88f3b531a46cd0 Mon Sep 17 00:00:00 2001 From: Andrene Date: Thu, 1 Jan 2026 14:07:54 -0500 Subject: [PATCH 4/6] caps fix --- sc2reader/engine/plugins/gameheart.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sc2reader/engine/plugins/gameheart.py b/sc2reader/engine/plugins/gameheart.py index 9b72953..c7994f4 100644 --- a/sc2reader/engine/plugins/gameheart.py +++ b/sc2reader/engine/plugins/gameheart.py @@ -67,7 +67,7 @@ def handleInitGame(self, event, replay): ) replay.start_time = datetime.fromtimestamp( replay.unix_timestamp - replay.real_length.seconds, - timezone.UTC + timezone.utc ) def fix_events(self, replay, start_frame): From 2605e5682d1d4a3747cb70046328b11241d344f7 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 1 Jan 2026 19:09:34 +0000 Subject: [PATCH 5/6] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- sc2reader/resources.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sc2reader/resources.py b/sc2reader/resources.py index 0eaf759..855bb27 100644 --- a/sc2reader/resources.py +++ b/sc2reader/resources.py @@ -412,7 +412,7 @@ def load_details(self): self.windows_timestamp = details["file_time"] self.unix_timestamp = utils.windows_to_unix(self.windows_timestamp) self.end_time = datetime.fromtimestamp( - self.unix_timestamp, + self.unix_timestamp, timezone.utc ) @@ -1093,7 +1093,7 @@ def __init__(self, summary_file, filename=None, lang="enUS", **options): self.expansion = "" self.end_time = datetime.fromtimestamp( - self.parts[0][8], + self.parts[0][8], timezone.utc ) self.game_speed = LOBBY_PROPERTIES[0xBB8][1][self.parts[0][0][1].decode("utf8")] From 1449803a91e5ba4f02268924ec5402d36c92e565 Mon Sep 17 00:00:00 2001 From: Andrene Date: Fri, 2 Jan 2026 15:45:29 -0500 Subject: [PATCH 6/6] set tzinfo for test to pass --- test_replays/test_replays.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test_replays/test_replays.py b/test_replays/test_replays.py index 4ea53c2..2afba66 100644 --- a/test_replays/test_replays.py +++ b/test_replays/test_replays.py @@ -1,4 +1,5 @@ import datetime +from datetime import timezone import json from xml.dom import minidom @@ -193,15 +194,15 @@ def test_datetimes(self): # Played at 20 Feb 2011 22:44:48 UTC+2 replay = sc2reader.load_replay("test_replays/1.2.2.17811/1.SC2Replay") - self.assertEqual(replay.end_time, datetime.datetime(2011, 2, 20, 20, 44, 47)) + self.assertEqual(replay.end_time, datetime.datetime(2011, 2, 20, 20, 44, 47, tzinfo=timezone.utc)) # Played at 21 Feb 2011 00:42:13 UTC+2 replay = sc2reader.load_replay("test_replays/1.2.2.17811/2.SC2Replay") - self.assertEqual(replay.end_time, datetime.datetime(2011, 2, 20, 22, 42, 12)) + self.assertEqual(replay.end_time, datetime.datetime(2011, 2, 20, 22, 42, 12, tzinfo=timezone.utc)) # Played at 25 Feb 2011 16:36:28 UTC+2 replay = sc2reader.load_replay("test_replays/1.2.2.17811/3.SC2Replay") - self.assertEqual(replay.end_time, datetime.datetime(2011, 2, 25, 14, 36, 26)) + self.assertEqual(replay.end_time, datetime.datetime(2011, 2, 25, 14, 36, 26, tzinfo=timezone.utc)) def test_hots_pids(self): for replayfilename in [