Show every time in US Eastern (America/New_York)
Webapp: config.DISPLAY_TZ (default America/New_York) and a local_dt filter that renders datetimes, ISO strings and Unix timestamps as e.g. "2026-10-05 13:54 EDT", DST included. Used for the ServiceNow tick list, technician to-do, imaging tiles and detail page; timestamp_fmt (reports, backups, enrollment) goes through it too instead of relying on the process TZ. CSV report_date is Eastern with its offset. Evidence-pack months are Eastern calendar months, so a wipe late on the 31st lands in that month rather than the next. Blancco: init points the new root's /etc/localtime at America/New_York so the GUI clock is local. Report timestamps keep their explicit offset; report.utc_offset stays 0 since a fixed offset cannot follow DST. Report file names stay UTC, as Blancco's own Save names them.
This commit is contained in:
@@ -638,7 +638,7 @@ def blancco_export_reports():
|
||||
if when < since:
|
||||
continue
|
||||
rows.extend(blancco_report.export_rows(
|
||||
f, data, when.isoformat(),
|
||||
f, data, to_display_tz(when).isoformat(),
|
||||
blancco_evidence.cloud_status(cloud_state, (data.get("meta") or {}).get("document_id", ""))))
|
||||
files.append(f)
|
||||
pdf = os.path.splitext(f)[0] + ".pdf"
|
||||
@@ -1490,10 +1490,40 @@ def api_save_unattend(image_type):
|
||||
# Template helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def to_display_tz(value):
|
||||
"""datetime (naive = UTC), ISO-8601 string or Unix timestamp -> aware
|
||||
datetime in config.DISPLAY_TZ; None when it cannot be read."""
|
||||
from datetime import timezone
|
||||
from zoneinfo import ZoneInfo
|
||||
if value is None or value == "":
|
||||
return None
|
||||
if isinstance(value, (int, float)):
|
||||
dt = datetime.fromtimestamp(value, timezone.utc)
|
||||
elif isinstance(value, datetime):
|
||||
dt = value if value.tzinfo else value.replace(tzinfo=timezone.utc)
|
||||
else:
|
||||
try:
|
||||
dt = datetime.fromisoformat(str(value).replace("Z", "+00:00"))
|
||||
except ValueError:
|
||||
return None
|
||||
if not dt.tzinfo:
|
||||
dt = dt.replace(tzinfo=timezone.utc)
|
||||
return dt.astimezone(ZoneInfo(config.DISPLAY_TZ))
|
||||
|
||||
|
||||
@app.template_filter("local_dt")
|
||||
def local_dt(value, seconds=False):
|
||||
"""Any timestamp shown in the UI, as e.g. '2026-10-05 13:54 EDT'."""
|
||||
dt = to_display_tz(value)
|
||||
if dt is None:
|
||||
return value or "-"
|
||||
return dt.strftime("%Y-%m-%d %H:%M:%S %Z" if seconds else "%Y-%m-%d %H:%M %Z")
|
||||
|
||||
|
||||
@app.template_filter("timestamp_fmt")
|
||||
def timestamp_fmt(ts):
|
||||
"""Format a Unix timestamp to a human-readable date string."""
|
||||
return datetime.fromtimestamp(ts).strftime("%Y-%m-%d %H:%M")
|
||||
"""Format a Unix timestamp in the display timezone."""
|
||||
return local_dt(ts)
|
||||
|
||||
|
||||
@app.context_processor
|
||||
|
||||
Reference in New Issue
Block a user