Provide lookup for normalized timezone names

This provides a helper to look up the correct timezone name independent
of the casing of the given timezone name.
This commit is contained in:
Martin Weinelt
2026-07-06 23:18:21 +02:00
parent f7528937e0
commit 38cabaa6aa
4 changed files with 29 additions and 8 deletions
+4 -1
View File
@@ -53,6 +53,7 @@ from frigate.util.file import (
)
from frigate.util.image import get_image_from_recording, get_image_quality_params
from frigate.util.media import get_keyframe_before
from frigate.util.time import get_normalized_tz_name
logger = logging.getLogger(__name__)
@@ -713,7 +714,9 @@ async def vod_hour(
parts = year_month.split("-")
start_date = (
datetime(int(parts[0]), int(parts[1]), day, hour, tzinfo=UTC)
- datetime.now(ZoneInfo(tz_name.replace(",", "/"))).utcoffset()
- datetime.now(
ZoneInfo(get_normalized_tz_name(tz_name.replace(",", "/")))
).utcoffset()
)
end_date = start_date + timedelta(hours=1) - timedelta(milliseconds=1)
start_ts = start_date.timestamp()
+4 -1
View File
@@ -22,6 +22,7 @@ from frigate.api.defs.response.preview_response import (
from frigate.api.defs.tags import Tags
from frigate.const import BASE_DIR, CACHE_DIR, PREVIEW_FRAME_TYPE
from frigate.models import Previews
from frigate.util.time import get_normalized_tz_name
logger = logging.getLogger(__name__)
@@ -126,7 +127,9 @@ def preview_hour(
parts = year_month.split("-")
start_date = (
datetime(int(parts[0]), int(parts[1]), int(day), int(hour), tzinfo=UTC)
- datetime.now(ZoneInfo(tz_name.replace(",", "/"))).utcoffset()
- datetime.now(
ZoneInfo(get_normalized_tz_name(tz_name.replace(",", "/")))
).utcoffset()
)
end_date = start_date + timedelta(hours=1) - timedelta(milliseconds=1)
start_ts = start_date.timestamp()
+3 -3
View File
@@ -31,7 +31,7 @@ from frigate.ffmpeg_presets import (
)
from frigate.models import Export, Previews, Recordings, ReviewSegment
from frigate.util.ffmpeg import run_ffmpeg_with_progress
from frigate.util.time import is_current_hour
from frigate.util.time import get_normalized_tz_name, is_current_hour
logger = logging.getLogger(__name__)
@@ -371,7 +371,7 @@ class RecordingExporter(threading.Thread):
tz_name = self.config.ui.timezone
if tz_name:
try:
tz = ZoneInfo(tz_name)
tz = ZoneInfo(get_normalized_tz_name(tz_name))
except (ValueError, ZoneInfoNotFoundError):
tz = None
if tz is not None:
@@ -533,7 +533,7 @@ class RecordingExporter(threading.Thread):
tz: datetime.tzinfo | None = None
if tz_name:
try:
tz = ZoneInfo(tz_name)
tz = ZoneInfo(get_normalized_tz_name(tz_name))
except (ValueError, ZoneInfoNotFoundError):
tz = None
if tz is None:
+18 -3
View File
@@ -2,16 +2,31 @@
import datetime
import logging
from zoneinfo import ZoneInfo, ZoneInfoNotFoundError
from typing import Final
from zoneinfo import ZoneInfo, ZoneInfoNotFoundError, available_timezones
from tzlocal import get_localzone
logger = logging.getLogger(__name__)
TIMEZONE_CASEFOLD_INDEX: Final = {
timezone.casefold(): timezone for timezone in available_timezones()
}
def get_normalized_tz_name(tz_name: str) -> str:
tz = TIMEZONE_CASEFOLD_INDEX.get(tz_name.casefold())
if tz:
return tz
raise ValueError(f"Unknown timezone: {tz_name}")
def get_tz_modifiers(tz_name: str) -> tuple[str, str, float]:
seconds_offset = (
datetime.datetime.now(ZoneInfo(tz_name)).utcoffset().total_seconds()
datetime.datetime.now(ZoneInfo(get_normalized_tz_name(tz_name)))
.utcoffset()
.total_seconds()
)
hours_offset = int(seconds_offset / 60 / 60)
minutes_offset = int(seconds_offset / 60 - hours_offset * 60)
@@ -58,7 +73,7 @@ def get_dst_transitions(
continuous periods with the same UTC offset
"""
try:
tz = ZoneInfo(tz_name)
tz = ZoneInfo(get_normalized_tz_name(tz_name))
except (ValueError, ZoneInfoNotFoundError):
# If timezone is invalid, return single period with no offset
return [(start_time, end_time, 0)]