Guides / RuntimeWarning: DateTimeField received a naive datetime

RuntimeWarning: DateTimeField received a naive datetime

Your logs fill up with RuntimeWarning: DateTimeField Event.starts_at received a naive datetime (2026-01-12 10:00:00) while time zone support is active. Nothing crashes, but times can be wrong by hours once your server's time zone differs from yours. Fix it by always using timezone-aware datetimes.

RuntimeWarning: DateTimeField Event.starts_at received a naive datetime (2026-01-12 10:00:00)
while time zone support is active.

What it means

With USE_TZ = True, Django stores datetimes in UTC and expects them to carry a time zone. A naive datetime has none. Django guesses by assuming it's in the current time zone (TIME_ZONE) and warns you. On your laptop that guess may be right. On a server set to UTC it quietly shifts every such value. USE_TZ has defaulted to True since Django 5.0; projects created earlier may still have it off.

Why it happens

  1. You use datetime.now() or datetime.utcnow() in model defaults, views or tasks. Both return naive values. (utcnow() is deprecated since Python 3.12.)
  2. You parse dates without a zone: datetime.strptime(...) or datetime(2026, 1, 12, 10, 0).
  3. Imported data has no offset (CSV, API responses, fixtures).
  4. The server's time zone differs from yours, which makes the wrong guess visible only after you deploy.

The fix

from datetime import datetime, timedelta
from zoneinfo import ZoneInfo

from django.utils import timezone

# "now" - use Django's helper (aware, in UTC when USE_TZ is True):
now = timezone.now()
soon = timezone.now() + timedelta(hours=2)

# a specific wall-clock time in a known zone:
meeting = datetime(2026, 1, 12, 10, 0, tzinfo=ZoneInfo("Europe/Amsterdam"))

# make an existing naive value aware (state the zone it is in):
aware = timezone.make_aware(naive_value, ZoneInfo("Europe/Amsterdam"))

# model defaults must be callables, never a fixed value:
created = models.DateTimeField(default=timezone.now)

Settings that go with it:

USE_TZ = True
TIME_ZONE = "UTC"      # store and compute in UTC; convert to local time only for display

Show local time in templates with the {% load tz %} filters ({{ value|localtime }} or timezone.activate() per user) and not by storing local values.

If your project still has USE_TZ = False, switching it on changes how existing values are read, so do it deliberately: back up, set USE_TZ = True with TIME_ZONE equal to the zone the old data was written in, and test on a copy of production.

Making it stick in production

import warnings

warnings.filterwarnings(
    "error",
    r"DateTimeField .* received a naive datetime",
    RuntimeWarning,
    r"django\.db\.models\.fields",
)

Or skip it

Django Cloud shows your app's logs in the dashboard with search and levels, so warnings like this one are easy to find, and you can fix them before a release goes live.

pip install djangocloud-cli
djangocloud deploy

Get startedSee pricing

Free plans are available for students, AWS Activate startups, open-source, non-profit and research projects. See how Django Cloud compares with other ways to host Django.

Django is a registered trademark of the Django Software Foundation. Django Cloud is not affiliated with or endorsed by it. Found a mistake in this guide? Tell us and we will fix it.