Skip to content

Fix timezone handling for archive timestamps (Borg 2.x readiness) #2390

@mr-raj12

Description

@mr-raj12

The problem

Archive timestamps from Borg are stored with timezone info stripped via .replace(tzinfo=None) in two locations:

  • src/vorta/borg/create.py:25
  • src/vorta/borg/list_repo.py:57

The existing TODO comment asks: "Keep as UTC?"

For Borg 1.x: Timestamps come without timezone suffix (already naive/local), so .replace(tzinfo=None) is a no-op. No impact today.

For Borg 2.x: Timestamps include UTC timezone info. Stripping it with .replace(tzinfo=None) stores the raw UTC value as a naive datetime, which then displays
as-is in the UI. A user in EST (UTC-5) would see a backup made at 9:24 AM local time displayed as "14:24" (the UTC value).

Display locations affected:

  • src/vorta/views/archive_tab.py:289-290 — .strftime('%Y-%m-%d %H:%M')
  • src/vorta/views/extract_dialog.py:115 — direct string conversion

Related: #185 flagged broader utcnow vs now inconsistency across models.

Requested Solution

Convert timezone-aware timestamps to local time before stripping tzinfo:

Instead of:

dt.fromisoformat(timestamp).replace(tzinfo=None)

Use:

dt.fromisoformat(timestamp).astimezone().replace(tzinfo=None)

.astimezone() with no argument converts to the system's local timezone. For Borg 1.x (naive input), fromisoformat returns naive datetime and .astimezone()
assumes local time — so it remains a no-op. For Borg 2.x (UTC input), it properly converts UTC → local before storing.

Apply in both create.py:25 and list_repo.py:57.

Alternatives

  1. Store as UTC and convert to local time only at display time (more correct but requires changing all display code)
  2. Store timezone-aware datetimes by switching from SQLite DateTimeField to storing ISO 8601 strings with offset (larger refactor)

Additional context

  • Low priority — only affects Borg 2.x which is still in beta
  • Two-line fix for the recommended solution
  • Broader datetime inconsistency across models (datetime.utcnow vs datetime.now) is a separate concern (see date/time findings #185)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions