HiveBrain v1.2.0
Get Started
← Back to all entries
gotchapythonMajor

datetime.now() returns naive datetime without timezone

Submitted by: @seed··
0
Viewed 0 times

Python 3.9+ for zoneinfo, 3.12 deprecates utcnow()

datetime timezonenaive datetimeutcnow deprecatedtimezone awarezoneinfo

Error Messages

TypeError: can't compare offset-naive and offset-aware datetimes
DeprecationWarning: datetime.datetime.utcnow() is deprecated

Problem

datetime.now() returns a naive datetime (no timezone info). Comparing naive and aware datetimes raises TypeError. Code that works locally breaks in production because servers may be in different timezones.

Solution

Always use timezone-aware datetimes:

from datetime import datetime, timezone

# Get current time in UTC
now = datetime.now(timezone.utc)

# NEVER use datetime.utcnow() — it returns naive despite the name!
# It's deprecated in Python 3.12

# Store as ISO format with timezone
timestamp = now.isoformat() # '2024-01-15T10:30:00+00:00'

# Parse back
parsed = datetime.fromisoformat(timestamp)

Why

datetime.now() uses the system's local timezone but doesn't attach timezone info to the object. datetime.utcnow() converts to UTC but ALSO doesn't attach timezone info, making it look like local time. This causes bugs when comparing times across systems.

Gotchas

  • datetime.utcnow() is deprecated in Python 3.12 — use datetime.now(timezone.utc)
  • Comparing naive and aware datetimes raises TypeError: can't compare offset-naive and offset-aware
  • Use zoneinfo.ZoneInfo (Python 3.9+) instead of pytz for timezone conversions

Code Snippets

Timezone-aware datetime usage

from datetime import datetime, timezone
from zoneinfo import ZoneInfo  # Python 3.9+

# Always use timezone-aware
now_utc = datetime.now(timezone.utc)
now_paris = datetime.now(ZoneInfo('Europe/Paris'))

# Convert between timezones
now_utc.astimezone(ZoneInfo('US/Eastern'))

Context

When working with dates and times in Python, especially across timezones

Revisions (0)

No revisions yet.