|
4 | 4 | # See LICENSE or go to <https://www.apache.org/licenses/LICENSE-2.0> for full license details.
|
5 | 5 |
|
6 | 6 |
|
| 7 | +from datetime import datetime |
7 | 8 | from io import StringIO
|
8 | 9 |
|
9 | 10 | import dash_leaflet as dl
|
10 | 11 | import pandas as pd
|
| 12 | +import pytz |
11 | 13 | import requests
|
12 | 14 | from dash import html
|
13 | 15 | from geopy import Point
|
14 | 16 | from geopy.distance import geodesic
|
| 17 | +from timezonefinder import TimezoneFinder |
15 | 18 |
|
16 | 19 | import config as cfg
|
17 | 20 |
|
18 | 21 | DEPARTMENTS = requests.get(cfg.GEOJSON_FILE, timeout=10).json()
|
19 | 22 |
|
20 | 23 |
|
| 24 | +tf = TimezoneFinder() |
| 25 | + |
| 26 | + |
| 27 | +def convert_dt_to_local_tz(lat, lon, str_utc_timestamp): |
| 28 | + """ |
| 29 | + Convert a UTC timestamp string to a local timezone string based on latitude and longitude. |
| 30 | +
|
| 31 | + Parameters: |
| 32 | + lat (float): Latitude of the location. |
| 33 | + lon (float): Longitude of the location. |
| 34 | + str_utc_timestamp (str): UTC timestamp string in ISO 8601 format (e.g., "2023-10-01T12:34:56"). |
| 35 | +
|
| 36 | + Returns: |
| 37 | + str: Local timezone string in the format "%Y-%m-%d %H:%M" or None if the input timestamp is invalid. |
| 38 | +
|
| 39 | + Example: |
| 40 | + >>> convert_dt_to_local_tz(48.8566, 2.3522, "2023-10-01T12:34:56") |
| 41 | + '2023-10-01 14:34' |
| 42 | + """ |
| 43 | + lat = round(lat, 4) |
| 44 | + lon = round(lon, 4) |
| 45 | + |
| 46 | + # Convert str_utc_timestamp to a timezone-aware datetime object assuming it's in UTC |
| 47 | + try: |
| 48 | + ts_utc = datetime.fromisoformat(str(str_utc_timestamp)).replace(tzinfo=pytz.utc) |
| 49 | + except ValueError: |
| 50 | + return None # Handle invalid datetime format |
| 51 | + |
| 52 | + # Find the local timezone |
| 53 | + timezone_str = tf.timezone_at(lat=lat, lng=lon) |
| 54 | + if timezone_str is None: # If the timezone is not found, handle it appropriately |
| 55 | + timezone_str = "UTC" # Fallback to UTC |
| 56 | + timezone = pytz.timezone(timezone_str) |
| 57 | + |
| 58 | + # Convert ts_utc to the local timezone |
| 59 | + return ts_utc.astimezone(timezone).strftime("%Y-%m-%d %H:%M") |
| 60 | + |
| 61 | + |
21 | 62 | def build_departments_geojson():
|
22 | 63 | """
|
23 | 64 | This function reads the departments.geojson file in the /data folder thanks to the json module
|
@@ -191,7 +232,13 @@ def create_event_list_from_alerts(api_events, cameras):
|
191 | 232 | ),
|
192 | 233 | style={"fontWeight": "bold"},
|
193 | 234 | ),
|
194 |
| - html.Div(event["started_at"].strftime("%Y-%m-%d %H:%M")), |
| 235 | + html.Div( |
| 236 | + convert_dt_to_local_tz( |
| 237 | + lat=cameras[cameras["id"] == event["camera_id"]]["lat"].values[0], |
| 238 | + lon=cameras[cameras["id"] == event["camera_id"]]["lon"].values[0], |
| 239 | + str_utc_timestamp=event["started_at"], |
| 240 | + ) |
| 241 | + ), |
195 | 242 | ],
|
196 | 243 | n_clicks=0,
|
197 | 244 | className="alert-card",
|
|
0 commit comments