mirror of
https://github.com/KnugiHK/WhatsApp-Chat-Exporter.git
synced 2026-04-27 08:21:33 +00:00
Merge pull request #206 from tang-vu/contribai/improve/quality/crash-in-timestamp-formatting-when-timez
✨ Quality: Crash in timestamp formatting when timezone_offset is None
This commit is contained in:
@@ -8,14 +8,14 @@ class Timing:
|
|||||||
Handles timestamp formatting with timezone support.
|
Handles timestamp formatting with timezone support.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, timezone_offset: Optional[int]) -> None:
|
def __init__(self, timezone_offset: Optional[Union[int, float]] = None) -> None:
|
||||||
"""
|
"""
|
||||||
Initialize Timing object.
|
Initialize Timing object.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
timezone_offset (Optional[int]): Hours offset from UTC
|
timezone_offset (Optional[Union[int, float]]): Hours offset from UTC. Defaults to None (auto-detect).
|
||||||
"""
|
"""
|
||||||
self.timezone_offset = timezone_offset
|
self.tz = TimeZone(timezone_offset) if timezone_offset is not None else None
|
||||||
|
|
||||||
def format_timestamp(self, timestamp: Optional[Union[int, float]], format: str) -> Optional[str]:
|
def format_timestamp(self, timestamp: Optional[Union[int, float]], format: str) -> Optional[str]:
|
||||||
"""
|
"""
|
||||||
@@ -30,7 +30,7 @@ class Timing:
|
|||||||
"""
|
"""
|
||||||
if timestamp is not None:
|
if timestamp is not None:
|
||||||
timestamp = timestamp / 1000 if timestamp > 9999999999 else timestamp
|
timestamp = timestamp / 1000 if timestamp > 9999999999 else timestamp
|
||||||
return datetime.fromtimestamp(timestamp, TimeZone(self.timezone_offset)).strftime(format)
|
return datetime.fromtimestamp(timestamp, self.tz).strftime(format)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
@@ -39,12 +39,12 @@ class TimeZone(tzinfo):
|
|||||||
Custom timezone class with fixed offset.
|
Custom timezone class with fixed offset.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, offset: int) -> None:
|
def __init__(self, offset: Union[int, float]) -> None:
|
||||||
"""
|
"""
|
||||||
Initialize TimeZone object.
|
Initialize TimeZone object.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
offset (int): Hours offset from UTC
|
offset (Union[int, float]): Hours offset from UTC
|
||||||
"""
|
"""
|
||||||
self.offset = offset
|
self.offset = offset
|
||||||
|
|
||||||
|
|||||||
55
tests/test_data_model.py
Normal file
55
tests/test_data_model.py
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
import pytest
|
||||||
|
from Whatsapp_Chat_Exporter.data_model import TimeZone, Timing
|
||||||
|
from datetime import timedelta
|
||||||
|
|
||||||
|
|
||||||
|
class TestTimeZone:
|
||||||
|
def test_utcoffset(self):
|
||||||
|
tz = TimeZone(5.5)
|
||||||
|
assert tz.utcoffset(None) == timedelta(hours=5.5)
|
||||||
|
|
||||||
|
def test_dst(self):
|
||||||
|
tz = TimeZone(2)
|
||||||
|
assert tz.dst(None) == timedelta(0)
|
||||||
|
|
||||||
|
|
||||||
|
class TestTiming:
|
||||||
|
@pytest.mark.parametrize("offset, expected_hour", [
|
||||||
|
(8, "08:00"), # Integer (e.g., Hong Kong Standard Time)
|
||||||
|
(-8, "16:00"), # Negative Integer (e.g., PST)
|
||||||
|
(5.5, "05:30"), # Positive Float (e.g., IST)
|
||||||
|
(-3.5, "20:30"), # Negative Float (e.g., Newfoundland)
|
||||||
|
])
|
||||||
|
|
||||||
|
def test_format_timestamp_various_offsets(self, offset, expected_hour):
|
||||||
|
"""Verify that both int and float offsets calculate time correctly."""
|
||||||
|
t = Timing(offset)
|
||||||
|
result = t.format_timestamp(1672531200, "%H:%M")
|
||||||
|
assert result == expected_hour
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("ts_input", [
|
||||||
|
1672531200, # Unix timestamp as int
|
||||||
|
1672531200.0, # Unix timestamp as float
|
||||||
|
])
|
||||||
|
|
||||||
|
def test_timestamp_input_types(self, ts_input):
|
||||||
|
"""Verify the method accepts both int and float timestamps."""
|
||||||
|
t = Timing(0)
|
||||||
|
result = t.format_timestamp(ts_input, "%Y")
|
||||||
|
assert result == "2023"
|
||||||
|
|
||||||
|
def test_timing_none_offset(self):
|
||||||
|
"""Verify initialization with None doesn't crash and uses system time."""
|
||||||
|
t = Timing(None)
|
||||||
|
assert t.tz is None
|
||||||
|
# Should still return a valid string based on local machine time without crashing
|
||||||
|
result = t.format_timestamp(1672531200, "%Y")
|
||||||
|
assert result == "2023"
|
||||||
|
|
||||||
|
def test_millisecond_scaling(self):
|
||||||
|
"""Verify that timestamps in milliseconds are correctly scaled down."""
|
||||||
|
t = Timing(0)
|
||||||
|
# Milliseconds as int
|
||||||
|
assert t.format_timestamp(1672531200000, "%Y") == "2023"
|
||||||
|
# Milliseconds as float
|
||||||
|
assert t.format_timestamp(1672531200000.0, "%Y") == "2023"
|
||||||
Reference in New Issue
Block a user