Django在将其保存到数据库时会损坏时区感知DateTimeField? [英] Is Django corrupting timezone-aware DateTimeField when saving it to the Database?

查看:258
本文介绍了Django在将其保存到数据库时会损坏时区感知DateTimeField?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Django模型,如描述 这里

I have a Django model as described here

我创建并保存此模型的实例:

I create and save an instance of this model:

>>> from django.db.models import Max, F, Func
>>> from django.conf import settings
>>> import pytz, datetime
>>> from myapp.models import myModel

>>> myModel.objects.all().delete()

>>> myModel.objects.create(
    my_date=datetime.datetime(2037,4,2,15,18,17,tzinfo=pytz.UTC), 
    my_string="asda"
)
<myModel: myModel object>

然后我尝试检索我刚刚插入的实例,但是我得到原生格式的DateTimeField申请 UNIX_TIMESTAMP

Then I try to retrieve the instance I just inserted, but I get the DateTimeField in native format and after applying UNIX_TIMESTAMP:

>>> x = myModel.objects.values('my_string').aggregate(
    max1=Max('my_date'), 
    max2=Max(Func(F('my_date'), function='UNIX_TIMESTAMP'))
)

>>> x
{
    'max2': Decimal('2122848857.000000'), 
    'max1': datetime.datetime(2037, 4, 8, 20, 14, 17, tzinfo=<UTC>)
}

>>> datetime.datetime.utcfromtimestamp(x["max2"])
datetime.datetime(2037, 4, 9, 0, 14, 17)


>>> pytz.timezone(settings.TIME_ZONE)
<DstTzInfo 'America/New_York' LMT-1 day, 19:04:00 STD>
>>> 

如果您转换 2122848857 返回DateTime,您将获得 2037-04-09T00:14:17 + 00 :00 。这比我实际插入的时间大4个小时。为什么?如何纠正这个看似腐败的问题?我的机器的时区是EDT,UTC后4个小时。但是,仍然不能解释为什么Django正在保存UTC时间,就像在当地的时区一样。

If you convert 2122848857 back to a DateTime, you get 2037-04-09T00:14:17+00:00. This is 4 hours greater than the time I actually inserted. Why? How to correct this seeming corruption? My machine's timezone is EDT which is 4 hours behind UTC. But that still doesn't explain why Django is saving this UTC time as if it was in my local timezone.

推荐答案

import pytz, datetime
from django.db.models import Max, F, Func
from django.conf import settings
from myapp.models import myModel

local_tz = pytz.timezone(settings.TIME_ZONE)

local_datetime = local_tz.localize(datetime.datetime(2037, 4, 8, 20, 14, 17), is_dst=None)
utc_datetime = local_datetime.astimezone(pytz.UTC)
# datetime.datetime(2037, 4, 9, 0, 14, 17, tzinfo=<UTC>)

MyModel.objects.create(my_date=utc_datetime)

x = MyModel.objects.aggregate(max1=Max('my_date'),max2=Max(Func(F('my_date'), function='UNIX_TIMESTAMP')))

pytz.UTC.localize(datetime.datetime.fromtimestamp(x['max2'])).astimezone(local_tz) == x['max1'].astimezone(local_tz)

这篇关于Django在将其保存到数据库时会损坏时区感知DateTimeField?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆