Skip to content

Commit

Permalink
Merge pull request #306 from OpenTrafficCam/feature/2332-time-stamps-…
Browse files Browse the repository at this point in the history
…in-utc-time-zone

feature/2332-time-stamps-in-utc-time-zone
  • Loading branch information
briemla committed Aug 22, 2023
2 parents 8db976d + a16f47c commit 4659978
Show file tree
Hide file tree
Showing 9 changed files with 47 additions and 33 deletions.
4 changes: 2 additions & 2 deletions OTAnalytics/application/analysis/traffic_counting.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from abc import ABC, abstractmethod
from collections import defaultdict
from dataclasses import dataclass
from datetime import datetime, timedelta
from datetime import datetime, timedelta, timezone
from typing import Iterable, Optional

from OTAnalytics.application.analysis.traffic_counting_specification import (
Expand Down Expand Up @@ -325,7 +325,7 @@ def create_tag(self, assignment: RoadUserAssignment) -> Tag:
original_time = int(assignment.events.start.occurrence.timestamp())
interval_seconds = self._interval.total_seconds()
result = int(original_time / interval_seconds) * interval_seconds
start_of_time_slot = datetime.fromtimestamp(result)
start_of_time_slot = datetime.fromtimestamp(result, timezone.utc)
return create_timeslot_tag(start_of_time_slot, self._interval)


Expand Down
8 changes: 4 additions & 4 deletions OTAnalytics/plugin_parser/otvision_parser.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import bz2
from abc import ABC, abstractmethod
from dataclasses import dataclass, field
from datetime import datetime
from datetime import datetime, timezone
from pathlib import Path
from typing import Any, Iterable, Optional, Sequence, Tuple

Expand Down Expand Up @@ -230,7 +230,7 @@ def __fix_occurrence(self, detection: dict, otdet_format_version: Version) -> di
if otdet_format_version <= Version(1, 1):
occurrence = datetime.strptime(
detection[ottrk_format.OCCURRENCE], ottrk_format.DATE_FORMAT
)
).replace(tzinfo=timezone.utc)
detection[ottrk_format.OCCURRENCE] = str(occurrence.timestamp())
return detection

Expand Down Expand Up @@ -384,7 +384,7 @@ def _parse_detections(
h=det_dict[ottrk_format.H],
frame=det_dict[ottrk_format.FRAME],
occurrence=datetime.fromtimestamp(
float(det_dict[ottrk_format.OCCURRENCE])
float(det_dict[ottrk_format.OCCURRENCE]), timezone.utc
),
input_file_path=path,
interpolated_detection=det_dict[ottrk_format.INTERPOLATED_DETECTION],
Expand Down Expand Up @@ -862,7 +862,7 @@ def parse(self, file: Path) -> OtConfig:
def _parse_project(self, data: dict) -> Project:
_validate_data(data, [project.NAME, project.START_DATE])
name = data[project.NAME]
start_date = datetime.fromtimestamp(data[project.START_DATE])
start_date = datetime.fromtimestamp(data[project.START_DATE], timezone.utc)
return Project(name=name, start_date=start_date)

def serialize(
Expand Down
3 changes: 2 additions & 1 deletion OTAnalytics/plugin_ui/customtkinter_gui/frame_filter.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import tkinter
from abc import ABC, abstractmethod
from datetime import datetime
from datetime import datetime, timezone
from tkinter import END, IntVar
from tkinter.ttk import Treeview
from typing import Any, Callable, Optional
Expand Down Expand Up @@ -438,6 +438,7 @@ def get_datetime(self) -> Optional[datetime]:
hour=int(self.hour),
minute=int(self.minute),
second=int(self.second),
tzinfo=timezone.utc,
)
except ValueError:
raise InvalidDatetimeFormatError(f"{self._name} datetime is not valid.")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from datetime import datetime, timedelta
from datetime import datetime, timedelta, timezone
from unittest.mock import Mock

import pytest
Expand Down Expand Up @@ -142,7 +142,9 @@ def create_event(
road_user_id=track_id.id,
road_user_type="car",
hostname="my_hostname",
occurrence=datetime(2020, 1, 1, 0, minute, second=real_seconds),
occurrence=datetime(
2020, 1, 1, 0, minute, second=real_seconds, tzinfo=timezone.utc
),
frame_number=1,
section_id=section,
event_coordinate=ImageCoordinate(0, 0),
Expand Down
29 changes: 16 additions & 13 deletions tests/OTAnalytics/application/test_track_filter.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from datetime import datetime
from datetime import datetime, timezone
from unittest.mock import Mock, patch

import pytest
Expand Down Expand Up @@ -31,22 +31,25 @@ class TestTrackPredicates:
@pytest.mark.parametrize(
"predicate, expected_result",
[
(TrackStartsAtOrAfterDate(datetime(2000, 1, 1)), True),
(TrackStartsAtOrAfterDate(datetime(2000, 1, 5)), False),
(TrackEndsBeforeOrAtDate(datetime(2000, 1, 3)), True),
(TrackEndsBeforeOrAtDate(datetime(2000, 1, 1)), False),
(TrackStartsAtOrAfterDate(datetime(2000, 1, 1, tzinfo=timezone.utc)), True),
(
TrackStartsAtOrAfterDate(datetime(2000, 1, 5, tzinfo=timezone.utc)),
False,
),
(TrackEndsBeforeOrAtDate(datetime(2000, 1, 3, tzinfo=timezone.utc)), True),
(TrackEndsBeforeOrAtDate(datetime(2000, 1, 1, tzinfo=timezone.utc)), False),
(TrackHasClassifications({"car", "truck"}), True),
(TrackHasClassifications({"bicycle", "truck"}), False),
(
TrackStartsAtOrAfterDate(datetime(2000, 1, 1)).conjunct_with(
TrackHasClassifications({"truck", "car"})
),
TrackStartsAtOrAfterDate(
datetime(2000, 1, 1, tzinfo=timezone.utc)
).conjunct_with(TrackHasClassifications({"truck", "car"})),
True,
),
(
TrackStartsAtOrAfterDate(datetime(2000, 1, 1)).conjunct_with(
TrackHasClassifications({"truck", "bicycle"})
),
TrackStartsAtOrAfterDate(
datetime(2000, 1, 1, tzinfo=timezone.utc)
).conjunct_with(TrackHasClassifications({"truck", "bicycle"})),
False,
),
],
Expand Down Expand Up @@ -136,7 +139,7 @@ def test_add_has_classifications_predicate(self) -> None:
assert track_filter._predicate._classifications == classifications

def test_add_multiple_predicates_fulfills(self, track: Track) -> None:
start_date = datetime(2000, 1, 1)
start_date = datetime(2000, 1, 1, tzinfo=timezone.utc)
classifications = {"car", "truck"}

builder = TrackFilterBuilder()
Expand All @@ -149,7 +152,7 @@ def test_add_multiple_predicates_fulfills(self, track: Track) -> None:
assert result == [track]

def test_add_multiple_predicates_not_fulfilled(self, track: Track) -> None:
start_date = datetime(2000, 1, 1)
start_date = datetime(2000, 1, 1, tzinfo=timezone.utc)
classifications = {"bicycle", "truck"}

builder = TrackFilterBuilder()
Expand Down
16 changes: 10 additions & 6 deletions tests/OTAnalytics/plugin_filter/test_dataframe_filter.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from datetime import datetime
from datetime import datetime, timezone
from typing import Iterable
from unittest.mock import Mock

Expand Down Expand Up @@ -64,11 +64,15 @@ class TestDataFramePredicates:
"predicate, expected_result",
[
(
DataFrameStartsAtOrAfterDate(OCCURRENCE, datetime(2000, 1, 1)),
DataFrameStartsAtOrAfterDate(
OCCURRENCE, datetime(2000, 1, 1, tzinfo=timezone.utc)
),
Series([True, True, True, True, True]),
),
(
DataFrameStartsAtOrAfterDate(OCCURRENCE, datetime(2000, 1, 10)),
DataFrameStartsAtOrAfterDate(
OCCURRENCE, datetime(2000, 1, 10, tzinfo=timezone.utc)
),
Series([False, False, False, False, False]),
),
(
Expand All @@ -81,15 +85,15 @@ class TestDataFramePredicates:
),
(
DataFrameStartsAtOrAfterDate(
OCCURRENCE, datetime(2000, 1, 1)
OCCURRENCE, datetime(2000, 1, 1, tzinfo=timezone.utc)
).conjunct_with(
DataFrameHasClassifications(CLASSIFICATION, {"car", "truck"}),
),
Series([True, True, True, True, True]),
),
(
DataFrameStartsAtOrAfterDate(
OCCURRENCE, datetime(2000, 1, 11)
OCCURRENCE, datetime(2000, 1, 11, tzinfo=timezone.utc)
).conjunct_with(
DataFrameHasClassifications(CLASSIFICATION, {"car", "truck"}),
),
Expand All @@ -108,7 +112,7 @@ def test_predicate(

class TestDataFrameFilter:
def test_filter_tracks_fulfill_all(self, track_dataframe: DataFrame) -> None:
start_date = datetime(2000, 1, 1)
start_date = datetime(2000, 1, 1, tzinfo=timezone.utc)
starts_at_or_after_date = DataFrameStartsAtOrAfterDate(OCCURRENCE, start_date)
has_classifications = DataFrameHasClassifications(
CLASSIFICATION, {"car", "truck"}
Expand Down
4 changes: 2 additions & 2 deletions tests/OTAnalytics/plugin_intersect/test_intersect.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from datetime import datetime
from datetime import datetime, timezone
from unittest.mock import Mock, patch

import pytest
Expand Down Expand Up @@ -631,7 +631,7 @@ def test_intersect_track_starts_outside_and_stays_inside_section(
road_user_id=1,
road_user_type="car",
hostname="myhostname",
occurrence=datetime(2020, 1, 1, 0, 0, 0, 1),
occurrence=datetime(2020, 1, 1, 0, 0, 0, 1, tzinfo=timezone.utc),
frame_number=2,
section_id=SectionId("N"),
event_coordinate=ImageCoordinate(1.5, 1.5),
Expand Down
6 changes: 4 additions & 2 deletions tests/OTAnalytics/plugin_parser/test_otvision_parser.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import bz2
from datetime import datetime
from datetime import datetime, timezone
from pathlib import Path
from typing import Any, Sequence
from unittest.mock import Mock, call
Expand Down Expand Up @@ -807,7 +807,9 @@ def test_parse_config(self, test_data_tmp_dir: Path) -> None:
video_parser=video_parser,
flow_parser=flow_parser,
)
project = Project(name="Test Project", start_date=datetime(2020, 1, 1))
project = Project(
name="Test Project", start_date=datetime(2020, 1, 1, tzinfo=timezone.utc)
)
videos: Sequence[Video] = ()
sections: Sequence[Section] = ()
flows: Sequence[Flow] = ()
Expand Down
4 changes: 3 additions & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import shutil
from dataclasses import dataclass
from datetime import datetime
from datetime import datetime, timezone
from pathlib import Path
from typing import Generator, Sequence, TypeVar

Expand Down Expand Up @@ -90,6 +90,7 @@ def create_detection(self) -> Detection:
self.occurrence_minute,
self.occurrence_second,
self.occurrence_microsecond,
tzinfo=timezone.utc,
),
input_file_path=Path(self.input_file_path),
interpolated_detection=self.interpolated_detection,
Expand Down Expand Up @@ -283,6 +284,7 @@ def build_section_event(self) -> Event:
self.occurrence_minute,
self.occurrence_second,
self.occurrence_microsecond,
tzinfo=timezone.utc,
),
frame_number=self.frame_number,
section_id=SectionId(self.section_id),
Expand Down

0 comments on commit 4659978

Please sign in to comment.