"""Tests for timestamp utilities.""" import pytest from datetime import datetime, timezone, timedelta from exchange_data_manager.utils.timestamps import ( to_millis, from_millis, to_seconds, from_seconds, ensure_tz_aware, now_millis, now_seconds, ) class TestToMillis: """Tests for to_millis function.""" def test_from_seconds(self): """Test converting seconds to milliseconds.""" assert to_millis(1709337600) == 1709337600000 def test_from_milliseconds(self): """Test that milliseconds pass through unchanged.""" assert to_millis(1709337600000) == 1709337600000 def test_from_float_seconds(self): """Test converting float seconds.""" assert to_millis(1709337600.5) == 1709337600500 def test_from_datetime_utc(self): """Test converting UTC datetime.""" dt = datetime(2024, 3, 2, 0, 0, 0, tzinfo=timezone.utc) assert to_millis(dt) == 1709337600000 def test_from_naive_datetime(self): """Test converting naive datetime (assumes UTC).""" dt = datetime(2024, 3, 2, 0, 0, 0) # Naive datetime treated as UTC assert to_millis(dt) == 1709337600000 def test_threshold_detection(self): """Test automatic detection of seconds vs milliseconds.""" # Values with realistic Unix-second magnitude are treated as seconds assert to_millis(1709337600) == 1709337600000 # Large values (including pre-2001 ms) are treated as milliseconds assert to_millis(999999999999) == 999999999999 assert to_millis(1000000000000) == 1000000000000 class TestFromMillis: """Tests for from_millis function.""" def test_to_datetime(self): """Test converting milliseconds to datetime.""" dt = from_millis(1709337600000) assert dt.year == 2024 assert dt.month == 3 assert dt.day == 2 assert dt.hour == 0 assert dt.minute == 0 assert dt.second == 0 def test_timezone_aware(self): """Test that result is timezone-aware.""" dt = from_millis(1709337600000) assert dt.tzinfo is not None assert dt.tzinfo == timezone.utc class TestToSeconds: """Tests for to_seconds function.""" def test_from_seconds(self): """Test that seconds pass through unchanged.""" assert to_seconds(1709337600) == 1709337600 def test_from_milliseconds(self): """Test converting milliseconds to seconds.""" assert to_seconds(1709337600000) == 1709337600 def test_historical_milliseconds_detected(self): """Test that historical ms timestamps are not misclassified as seconds.""" assert to_seconds(999999999999) == 999999999 def test_from_datetime(self): """Test converting datetime to seconds.""" dt = datetime(2024, 3, 2, 0, 0, 0, tzinfo=timezone.utc) assert to_seconds(dt) == 1709337600 class TestFromSeconds: """Tests for from_seconds function.""" def test_to_datetime(self): """Test converting seconds to datetime.""" dt = from_seconds(1709337600) assert dt.year == 2024 assert dt.month == 3 assert dt.day == 2 def test_timezone_aware(self): """Test that result is timezone-aware.""" dt = from_seconds(1709337600) assert dt.tzinfo == timezone.utc class TestEnsureTzAware: """Tests for ensure_tz_aware function.""" def test_naive_becomes_utc(self): """Test that naive datetime becomes UTC.""" dt = datetime(2024, 3, 2, 0, 0, 0) result = ensure_tz_aware(dt) assert result.tzinfo == timezone.utc def test_aware_unchanged(self): """Test that aware datetime is unchanged.""" dt = datetime(2024, 3, 2, 0, 0, 0, tzinfo=timezone.utc) result = ensure_tz_aware(dt) assert result == dt def test_different_timezone_normalized_to_utc(self): """Test that non-UTC timezone is normalized to UTC.""" tz = timezone(timedelta(hours=5)) dt = datetime(2024, 3, 2, 0, 0, 0, tzinfo=tz) result = ensure_tz_aware(dt) assert result.tzinfo == timezone.utc assert result.year == 2024 assert result.month == 3 assert result.day == 1 assert result.hour == 19 class TestNowFunctions: """Tests for now_millis and now_seconds functions.""" def test_now_millis_reasonable(self): """Test that now_millis returns a reasonable value.""" ms = now_millis() # Should be after 2024-01-01 in milliseconds assert ms > 1704067200000 # Should be a large number (milliseconds) assert ms >= 1e12 def test_now_seconds_reasonable(self): """Test that now_seconds returns a reasonable value.""" s = now_seconds() # Should be after 2024-01-01 in seconds assert s > 1704067200 # Should be a smaller number (seconds) assert s < 1e12 def test_consistency(self): """Test that now_millis and now_seconds are consistent.""" ms = now_millis() s = now_seconds() # Should be within 1 second of each other assert abs(ms // 1000 - s) <= 1