diff --git a/src/corelibs/string_handling/timestamp_strings.py b/src/corelibs/string_handling/timestamp_strings.py index 68346de..ae3fea9 100644 --- a/src/corelibs/string_handling/timestamp_strings.py +++ b/src/corelibs/string_handling/timestamp_strings.py @@ -28,7 +28,7 @@ class TimestampStrings: self.time_zone = time_zone if time_zone is not None else self.TIME_ZONE try: self.timestamp_now_tz = datetime.now( - ZoneInfo(self.time_zone) if not isinstance(self.time_zone, ZoneInfo) else self.time_zone + ZoneInfo(self.time_zone) if isinstance(self.time_zone, str) else self.time_zone ) except ZoneInfoNotFoundError as e: raise ValueError(f'Zone could not be loaded [{self.time_zone}]: {e}') from e diff --git a/test-run/timestamp_strings/timestamp_strings.py b/test-run/timestamp_strings/timestamp_strings.py index dcf8109..b4fd464 100644 --- a/test-run/timestamp_strings/timestamp_strings.py +++ b/test-run/timestamp_strings/timestamp_strings.py @@ -22,6 +22,9 @@ def main(): print(f"TZ: {ts.time_zone} -> TS: {ts.timestamp_now_tz}") ts = TimestampStrings(ZoneInfo("Europe/Vienna")) print(f"TZ: {ts.time_zone} -> TS: {ts.timestamp_now_tz}") + custom_tz = 'Europe/Paris' + ts = TimestampStrings(time_zone=custom_tz) + print(f"TZ: {ts.time_zone} -> TS: {ts.timestamp_now_tz}") if __name__ == "__main__": diff --git a/tests/unit/string_handling/test_timestamp_strings.py b/tests/unit/string_handling/test_timestamp_strings.py index 433f11d..d9d0522 100644 --- a/tests/unit/string_handling/test_timestamp_strings.py +++ b/tests/unit/string_handling/test_timestamp_strings.py @@ -3,7 +3,7 @@ PyTest: string_handling/timestamp_strings """ from datetime import datetime -from unittest.mock import patch, MagicMock +from unittest.mock import patch from zoneinfo import ZoneInfo import pytest @@ -119,18 +119,55 @@ class TestTimestampStrings: assert ts2.time_zone == 'Europe/London' assert ts1.time_zone != ts2.time_zone - @patch('corelibs.string_handling.timestamp_strings.ZoneInfo') - def test_zoneinfo_called_correctly(self, mock_zoneinfo: MagicMock): - """Test that ZoneInfo is called with correct timezone""" + def test_zoneinfo_called_correctly_with_string(self): + """Test that ZoneInfo is called with correct timezone when passing string""" + with patch('corelibs.string_handling.timestamp_strings.ZoneInfo') as mock_zoneinfo: + with patch('corelibs.string_handling.timestamp_strings.datetime') as mock_datetime: + mock_now = datetime(2023, 12, 25, 15, 30, 45) + mock_datetime.now.return_value = mock_now + + custom_tz = 'Europe/Paris' + ts = TimestampStrings(time_zone=custom_tz) + assert ts.time_zone == custom_tz + + mock_zoneinfo.assert_called_with(custom_tz) + + def test_zoneinfo_object_parameter(self): + """Test that ZoneInfo objects can be passed directly as timezone parameter""" with patch('corelibs.string_handling.timestamp_strings.datetime') as mock_datetime: mock_now = datetime(2023, 12, 25, 15, 30, 45) - mock_datetime.now.return_value = mock_now + mock_now_tz = datetime(2023, 12, 25, 15, 30, 45, tzinfo=ZoneInfo('Europe/Paris')) + mock_datetime.now.side_effect = [mock_now, mock_now_tz] - custom_tz = 'Europe/Paris' - ts = TimestampStrings(time_zone=custom_tz) - assert ts.time_zone == custom_tz + # Create a ZoneInfo object + custom_tz_obj = ZoneInfo('Europe/Paris') + ts = TimestampStrings(time_zone=custom_tz_obj) - mock_zoneinfo.assert_called_with(custom_tz) + # The time_zone should be the ZoneInfo object itself + assert ts.time_zone is custom_tz_obj + assert isinstance(ts.time_zone, ZoneInfo) + + def test_zoneinfo_object_vs_string_equivalence(self): + """Test that ZoneInfo object and string produce equivalent results""" + with patch('corelibs.string_handling.timestamp_strings.datetime') as mock_datetime: + mock_now = datetime(2023, 12, 25, 15, 30, 45) + mock_now_tz = datetime(2023, 12, 25, 15, 30, 45, tzinfo=ZoneInfo('Europe/Paris')) + mock_datetime.now.side_effect = [mock_now, mock_now_tz, mock_now, mock_now_tz] + + # Test with string + ts_string = TimestampStrings(time_zone='Europe/Paris') + + # Test with ZoneInfo object + ts_zoneinfo = TimestampStrings(time_zone=ZoneInfo('Europe/Paris')) + + # Both should produce the same timestamp formats (though time_zone attributes will differ) + assert ts_string.today == ts_zoneinfo.today + assert ts_string.timestamp == ts_zoneinfo.timestamp + assert ts_string.timestamp_file == ts_zoneinfo.timestamp_file + + # The time_zone attributes will be different types but represent the same timezone + assert str(ts_string.time_zone) == 'Europe/Paris' + assert isinstance(ts_zoneinfo.time_zone, ZoneInfo) def test_edge_case_midnight(self): """Test timestamp formatting at midnight""" diff --git a/uv.lock b/uv.lock index bc1d46b..3753dc0 100644 --- a/uv.lock +++ b/uv.lock @@ -53,7 +53,7 @@ wheels = [ [[package]] name = "corelibs" -version = "0.24.1" +version = "0.24.2" source = { editable = "." } dependencies = [ { name = "jmespath" },