JSONField: Better handling of non-UTC dates #95

acdha opened this Issue Apr 7, 2011 · 6 comments

5 participants


https://github.com/django-extensions/django-extensions/blob/master/django_extensions/db/fields/json.py#L26 causes assertion failures if the system timezone isn't UTC. It would be preferable to support datetime's native tz handling if e.g. pytz is installed rather than simply crashing.


In one use case I'd be storing datetime.datetime.utcnow() values in a JSONField and later comparing those against one another. I don't think that settings.TIME_ZONE would even have any effect in this case.

Maybe a warning about timezone issues in the documentation would suffice?


It's also somewhat annoying that this breaks when you set settings.TIME_ZONE to None and the machine's timezone is set to UTC.


I've proposed the following solution within our group - how does this sound? I thought about using pytz but I think this simple approach of requiring that the user either provide non-naive datetime instances or that the system time zone be UTC is sufficient:

# See http://docs.python.org/library/datetime.html
from datetime import tzinfo, timedelta, datetime

ZERO = timedelta(0)
HOUR = timedelta(hours=1)

class UTC(tzinfo):

    def utcoffset(self, dt):
        return ZERO

    def tzname(self, dt):
        return "UTC"

    def dst(self, dt):
        return ZERO

utc = UTC()

class JSONEncoder(simplejson.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, Decimal):
            return str(obj)
        elif isinstance(obj, datetime.datetime):
            if obj.tzinfo is None:
                assert settings.TIME_ZONE == 'UTC'
                obj = obj.astimezone(utc)
            return obj.strftime('%Y-%m-%dT%H:%M:%SZ')
        return simplejson.JSONEncoder.default(self, obj)
@acdha acdha added a commit to acdha/django-extensions that referenced this issue Aug 2, 2012
@acdha acdha JSONField: handle non-UTC dates (closes #95)
Extends the JSONField implementation to allow arbitrary timezones
as long as the user passes in non-naive datetime instances. Naive
values are still handled as in the past, requiring
settings.TIME_ZONE to be UTC.

Minor PEP8 cleanup
Django Extensions member

@acdha django already handles this, recently it was integrated into django-extensions, so it now uses it by default.


Seems you can close this issue.


@camilonova Was that added in Django 1.5 or 1.6? It does sound like we could simply close this either way since the release schedule for 1.6 and 1.7 is pretty aggressive and there's less reason to say django-extensions needs to care about anything which is more than one or two major releases back.

Django Extensions member

@acdha thats right, it was added in Django 1.5 so seems reasonable to close this issue.

@trbs trbs closed this Oct 6, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment