diff --git a/backend/app/routers/photos.py b/backend/app/routers/photos.py index 9c76500..aecc977 100644 --- a/backend/app/routers/photos.py +++ b/backend/app/routers/photos.py @@ -2,7 +2,7 @@ Photos API router """ from typing import List, Optional, Dict, Any -from datetime import datetime +from datetime import datetime, timezone from pathlib import Path from fastapi import APIRouter, Depends, HTTPException, Query, Response from fastapi.responses import FileResponse @@ -888,6 +888,15 @@ async def update_photo( if 'taken_at' in update_data: new_dt = update_data.pop('taken_at') if new_dt is not None: + # The frontend's usually serializes + # without a tz, but a manual edit / paste / certain locales can + # send a tz-aware ISO (e.g. "2026-05-09T00:12+02:00"). The + # photos.taken_at column is `timestamp without time zone`, so + # asyncpg can't bind a tz-aware value — it raises + # "can't subtract offset-naive and offset-aware datetimes". + # Normalize to naive UTC so both shapes round-trip cleanly. + if new_dt.tzinfo is not None: + new_dt = new_dt.astimezone(timezone.utc).replace(tzinfo=None) try: await write_taken_at(photo.filepath, new_dt) except ExifWriteError as exc: