Skip to content

Instantly share code, notes, and snippets.

@denilsonsa
Forked from anonymous/dpaste.de_snippet.py
Last active August 29, 2015 14:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save denilsonsa/d94a326f8d169105fc39 to your computer and use it in GitHub Desktop.
Save denilsonsa/d94a326f8d169105fc39 to your computer and use it in GitHub Desktop.
datetime object, when rendered to Django template, was always 6 minutes off.
class LocalDateTimeField(with_metaclass(models.SubfieldBase, models.DateTimeField)):
'''A hack/workaround version of DateTimeField that considers the datetime
from the database as local time.
'''
def to_python(self, value):
from django.utils.dateformat import format
value = models.DateTimeField.to_python(self, value)
if isinstance(value, datetime):
print('-' + repr(value))
print(strftime('%Y-%m-%d %H:%M:%S.%f', value.timetuple()))
print(format(value, 'd F Y, H:i'))
value = value.replace(tzinfo=get_default_timezone())
print('+' + repr(value))
print(strftime('%Y-%m-%d %H:%M:%S.%f', value.timetuple()))
print(format(value, 'd F Y, H:i'))
return value
# I have a model with a LocalDateTimeField.
obj = MyModel.objects.get(id=1234)
repr(obj.datefield)
# datetime.datetime(2014, 7, 3, 17, 7, 3, tzinfo=<DstTzInfo 'America/Sao_Paulo' LMT-1 day, 20:54:00 STD>)
from django.template import Context,Template
templ = Template('Date: {{ d|date:"d F Y, H:i:s" }}')
templ.render(Context({'d': obj.datefield}))
# 'Date: 03 July 2014, 17:13:03'
# WTF?
# Why the object is 17:07:03 and the printed version from the template is 17:13:03
# The normalize() method was changing the time:
# https://bazaar.launchpad.net/~stub/pytz/devel/view/head:/src/pytz/tzinfo.py#L238
dt.tzinfo._utcoffset
# datetime.timedelta(-1, 75240)
75240 / 60 / 60
# 20.9 hours! WAT?
# Reason: https://stackoverflow.com/questions/18255024/pytz-utcoffset-has-a-wrong-value-for-iran
#
# THIS IS WRONG, don't use it:
# value = value.replace(tzinfo=get_default_timezone())
#
# Solution:
value = get_current_timezone().localize(value.replace(tzinfo=None))
# datetime.datetime(2014, 7, 3, 17, 7, 3, tzinfo=<DstTzInfo 'America/Sao_Paulo' BRT-1 day, 21:00:00 STD>)
# Note it is now BRT, and not LMT.
# See also:
# https://github.com/django/django/blob/1.6.5/django/utils/timezone.py#L298
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment