fix timezone-aware timestamp

This commit is contained in:
lelo 2025-04-02 06:36:03 +00:00
parent b500496176
commit 35d204d9b0
3 changed files with 73 additions and 14 deletions

View File

@ -1,6 +1,6 @@
import sqlite3
from flask import render_template, request, session
from datetime import datetime, timedelta
from datetime import datetime, timedelta, timezone
import geoip2.database
from auth import require_secret
import os
@ -59,7 +59,8 @@ def get_device_type(user_agent):
def log_file_access(rel_path, filesize, mime, ip_address, user_agent, device_id, cached):
"""Insert a file access record into the database and prune entries older than 10 minutes."""
global file_access_temp
timestamp = datetime.now()
# Create a timezone-aware timestamp (local time with offset)
timestamp = datetime.now(timezone.utc).astimezone()
iso_ts = timestamp.isoformat()
with log_db:
@ -70,7 +71,7 @@ def log_file_access(rel_path, filesize, mime, ip_address, user_agent, device_id,
''', (iso_ts, rel_path, filesize, mime, ip_address, user_agent, device_id, cached))
# Remove entries older than 10 minutes
cutoff_time = datetime.now() - timedelta(minutes=10)
cutoff_time = datetime.now(timezone.utc).astimezone() - timedelta(minutes=10)
file_access_temp[:] = [
entry for entry in file_access_temp
if datetime.fromisoformat(entry[0]) >= cutoff_time
@ -81,9 +82,19 @@ def log_file_access(rel_path, filesize, mime, ip_address, user_agent, device_id,
return True
def return_file_access():
"""Return recent file access logs from memory."""
"""Return recent file access logs from memory (the last 10 minutes)."""
global file_access_temp
if file_access_temp:
# Create a timezone-aware cutoff time
cutoff_time = datetime.now(timezone.utc).astimezone() - timedelta(minutes=10)
# Only keep entries with timestamps greater than or equal to cutoff_time
file_access_temp[:] = [
entry for entry in file_access_temp
if datetime.fromisoformat(entry[0]) >= cutoff_time
]
return file_access_temp
else:
return []
@require_secret
def connections():
@ -162,7 +173,7 @@ def dashboard():
if session['timeframe'] == 'last24hours':
# Group by hour: substr(timestamp, 12, 2) -> HH
query = f'''
SELECT substr(timestamp, 1, 13) AS bucket, COUNT(DISTINCT device_id) AS count
SELECT strftime('%Y-%m-%dT%H:00:00Z', replace(timestamp, 'T', ' ')) AS bucket, COUNT(DISTINCT device_id) AS count
FROM file_access_log
WHERE timestamp >= ? {filetype_filter_sql}
GROUP BY bucket
@ -207,7 +218,7 @@ def dashboard():
if session['timeframe'] == 'last24hours':
# Hour: substr(timestamp, 12, 2) -> HH
query = f'''
SELECT substr(timestamp, 1, 13) AS bucket, COUNT(*) AS count
SELECT strftime('%Y-%m-%dT%H:00:00Z', replace(timestamp, 'T', ' ')) AS bucket, COUNT(*) AS count
FROM file_access_log
WHERE timestamp >= ? {filetype_filter_sql}
GROUP BY bucket

48
convert_db.py Normal file
View File

@ -0,0 +1,48 @@
#!/usr/bin/env python3
import sqlite3
from datetime import datetime, timezone
# Name of your SQLite database file
DB_NAME = 'access_log.db'
def convert_naive_to_timezone_aware(naive_ts):
"""
Convert a naive ISO timestamp (assumed to be in local time) into a timezone-aware timestamp.
"""
try:
dt = datetime.fromisoformat(naive_ts)
except Exception as e:
print(f"Error parsing timestamp {naive_ts}: {e}")
return naive_ts # If parsing fails, return the original value
# If the timestamp is naive (i.e., no tzinfo), make it timezone-aware by assuming it's local time.
if dt.tzinfo is None:
# Get the local timezone info using the current time's offset.
local_tz = datetime.now(timezone.utc).astimezone().tzinfo
dt = dt.replace(tzinfo=local_tz)
return dt.isoformat()
else:
# Timestamp is already timezone-aware
return naive_ts
def update_database():
conn = sqlite3.connect(DB_NAME)
cursor = conn.cursor()
# Fetch all records' IDs and timestamps
cursor.execute("SELECT id, timestamp FROM file_access_log")
rows = cursor.fetchall()
updated_count = 0
for rec_id, ts in rows:
new_ts = convert_naive_to_timezone_aware(ts)
if new_ts != ts:
cursor.execute("UPDATE file_access_log SET timestamp = ? WHERE id = ?", (new_ts, rec_id))
updated_count += 1
conn.commit()
conn.close()
print(f"Updated {updated_count} records to timezone-aware timestamps.")
if __name__ == "__main__":
update_database()

View File

@ -216,18 +216,18 @@
const timeframe = "{{ timeframe }}"; // e.g., 'last24hours', '7days', '30days', or '365days'
const shiftedLabels = timeframeData.map(item => {
if (timeframe === 'last24hours') {
// item.bucket will be something like "2025-04-01T15"
const bucketDate = new Date(item.bucket + ":00:00"); // Convert to a full datetime by appending minutes and seconds.
// item.bucket is now in the format "YYYY-MM-DDTHH:00:00Z"
const bucketDate = new Date(item.bucket);
const now = new Date();
// Check if this bucket corresponds to the current hour
// Check if this bucket corresponds to the current hour (in client's local time)
const isCurrentHour =
bucketDate.getFullYear() === now.getFullYear() &&
bucketDate.getMonth() === now.getMonth() &&
bucketDate.getDate() === now.getDate() &&
bucketDate.getHours() === now.getHours();
// If it is the current hour, use the current time as the end; otherwise, add one hour.
// For the current hour, use the current time as the bucket end.
const bucketEnd = isCurrentHour ? now : new Date(bucketDate.getTime() + 3600 * 1000);
return `${bucketDate.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })} - ${bucketEnd.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}`;