FE+BE: timexone fixes 1 #1440

Signed-off-by: jokob-sk <jokob.sk@gmail.com>
This commit is contained in:
jokob-sk
2026-02-01 15:48:28 +11:00
parent 56ba8864da
commit 2954b929a6
3 changed files with 55 additions and 16 deletions

View File

@@ -450,10 +450,18 @@ function localizeTimestamp(input) {
const date = new Date(str);
if (!isFinite(date)) {
console.error(`ERROR: Couldn't parse date: '${str}' with TIMEZONE ${tz}`);
return 'Failed conversion - Check browser console';
return 'Failed conversion';
}
// CHECK: Does the input string have an offset (e.g., +11:00 or Z)?
// If it does, and we apply a 'tz' again, we double-shift.
const hasOffset = /[Z|[+-]\d{2}:?\d{2}]$/.test(str.trim());
return new Intl.DateTimeFormat(LOCALE, {
timeZone: tz,
// If it has an offset, we display it as-is (UTC mode in Intl
// effectively means "don't add more hours").
// If no offset, apply your variable 'tz'.
timeZone: hasOffset ? 'UTC' : tz,
year: 'numeric', month: '2-digit', day: '2-digit',
hour: '2-digit', minute: '2-digit', second: '2-digit',
hour12: false

View File

@@ -18,7 +18,7 @@ from db.authoritative_handler import (
unlock_fields
)
from helper import is_random_mac, get_setting_value
from utils.datetime_utils import timeNowDB, format_date
from utils.datetime_utils import timeNowDB
class DeviceInstance:
@@ -489,8 +489,8 @@ class DeviceInstance:
return None
device_data = row_to_json(list(row.keys()), row)
device_data["devFirstConnection"] = format_date(device_data["devFirstConnection"])
device_data["devLastConnection"] = format_date(device_data["devLastConnection"])
device_data["devFirstConnection"] = device_data["devFirstConnection"]
device_data["devLastConnection"] = device_data["devLastConnection"]
device_data["devIsRandomMAC"] = is_random_mac(device_data["devMac"])
# Fetch children

View File

@@ -112,12 +112,29 @@ def normalizeTimeStamp(inputTimeStamp):
# -------------------------------------------------------------------------------------------
def format_date_iso(date1: str) -> Optional[str]:
"""Return ISO 8601 string for a date or None if empty"""
if not date1:
def format_date_iso(date_val: str) -> Optional[str]:
"""Ensures a date string from DB is returned as a proper ISO string with TZ."""
if not date_val:
return None
dt = datetime.datetime.fromisoformat(date1) if isinstance(date1, str) else date1
return dt.isoformat()
try:
# 1. Parse the string from DB (e.g., "2026-01-20 07:58:18")
if isinstance(date_val, str):
# Use a more flexible parser if it's not strict ISO
dt = datetime.datetime.fromisoformat(date_val.replace(" ", "T"))
else:
dt = date_val
# 2. If it has no timezone, ATTACH (don't convert) your config TZ
if dt.tzinfo is None:
target_tz = conf.tz if isinstance(conf.tz, datetime.tzinfo) else ZoneInfo(conf.tz)
dt = dt.replace(tzinfo=target_tz)
# 3. Return the string. .isoformat() will now include the +11:00 or +10:00
return dt.isoformat()
except Exception as e:
print(f"Error formatting date: {e}")
return str(date_val)
# -------------------------------------------------------------------------------------------
@@ -156,21 +173,35 @@ def parse_datetime(dt_str):
def format_date(date_str: str) -> str:
try:
if isinstance(date_str, str):
# collapse all whitespace into single spaces
date_str = re.sub(r"\s+", " ", date_str.strip())
if not date_str:
return ""
date_str = re.sub(r"\s+", " ", str(date_str).strip())
dt = parse_datetime(date_str)
if dt.tzinfo is None:
if isinstance(conf.tz, str):
dt = dt.replace(tzinfo=ZoneInfo(conf.tz))
else:
dt = dt.replace(tzinfo=conf.tz)
if not dt:
return f"invalid:{repr(date_str)}"
# If the DB has no timezone, we tell Python what it IS,
# we don't CONVERT it.
if dt.tzinfo is None:
# Option A: If the DB time is already AEDT, use AEDT.
# Option B: Use conf.tz if that is your 'source of truth'
dt = dt.replace(tzinfo=conf.tz)
return dt.astimezone().isoformat()
# IMPORTANT: Return the ISO format of the object AS IS.
# Calling .astimezone() here triggers a conversion to the
# System Local Time , which is causing your shift.
return dt.isoformat()
except Exception:
return f"invalid:{repr(date_str)}"
except Exception as e:
return f"invalid:{repr(date_str)} e: {e}"
def format_date_diff(date1, date2, tz_name):