From 49bb352eaf4c078d3f5540f2232a36d6ca675c00 Mon Sep 17 00:00:00 2001 From: Shahadat Islam Koyel <179203101+ShahadatTest@users.noreply.github.com> Date: Tue, 27 Oct 2026 17:11:27 +0600 Subject: [PATCH] Preserve aware datetime timezones in format_time --- _python_utils_tests/test_time.py | 31 +++++++++++++++++++++++++++++++ python_utils/time.py | 9 ++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/_python_utils_tests/test_time.py b/_python_utils_tests/test_time.py index b30d7c5..5e2550f 100644 --- a/_python_utils_tests/test_time.py +++ b/_python_utils_tests/test_time.py @@ -585,3 +585,34 @@ async def letters() -> types.AsyncGenerator[str, None]: assert items == ['a', 'b', 'c'] assert sleeps == [1, 1, 1] + + +@pytest.mark.parametrize( + 'minutes,expected', + [ + (0, '2000-01-02 03:04:05+00:00'), + (330, '2000-01-02 03:04:05+05:30'), + (-210, '2000-01-02 03:04:05-03:30'), + ], +) +def test_format_time_preserves_datetime_timezone( + minutes: int, expected: str +) -> None: + """Truncate an aware datetime without converting it to local time.""" + value = datetime.datetime( + 2000, + 1, + 2, + 3, + 4, + 5, + 123456, + tzinfo=datetime.timezone(datetime.timedelta(minutes=minutes)), + ) + assert python_utils.format_time(value) == expected + + +def test_format_time_naive_datetime_control() -> None: + """Keep the existing local-time representation for naive datetimes.""" + value = datetime.datetime(2000, 1, 2, 3, 4, 5, 123456) + assert python_utils.format_time(value) == '2000-01-02 03:04:05' diff --git a/python_utils/time.py b/python_utils/time.py index f4fb5af..704b212 100644 --- a/python_utils/time.py +++ b/python_utils/time.py @@ -124,6 +124,13 @@ def format_time( '0:00:01' >>> format_time(datetime.datetime(2000, 1, 2, 3, 4, 5, 6)) '2000-01-02 03:04:05' + + Aware datetimes keep their timezone in the formatted result. + + >>> format_time( + ... datetime.datetime(2000, 1, 2, tzinfo=datetime.timezone.utc) + ... ) + '2000-01-02 00:00:00+00:00' >>> format_time(datetime.date(2000, 1, 2)) '2000-01-02' >>> format_time(datetime.timedelta(seconds=3661)) @@ -165,7 +172,7 @@ def format_time( seconds = (since_epoch - since_epoch % precision).total_seconds() try: # pragma: no cover - dt = datetime.datetime.fromtimestamp(seconds) + dt = datetime.datetime.fromtimestamp(seconds, timestamp.tzinfo) except (ValueError, OSError): # pragma: no cover dt = datetime.datetime.max return str(dt)