Django的如何正确节省时间和时区

问题描述

我有这段代码表现得很奇怪,并且提出了一个问题,我应该如何处理时区?因此,首先,我有一个根据用户发布的信息构建的datetime对象:

time_zone = request.POST.get("time_zone")
date_start = request.POST.get("date_start")
time_day = request.POST.get("time_day")

time_zone_obj = pytz.timezone("Etc/" + time_zone)  # GMT + 2 in this example
date_start = datetime.strptime(date_start,"%d/%m/%Y")
date_start = date_start.replace(tzinfo=time_zone_obj)
time_day = datetime.strptime(time_day,"%I:%M %p")
date_start = date_start.replace(hour=time_day.hour,minute=time_day.minute)

...
event.date_start = date_start
event.save()
print("event.date_start.hour:%s" % event.date_start.hour)
print("event.date_start.tzinfo:%s" % event.date_start.tzinfo)
print("is_aware(event.date_start:%s)" % is_aware(event.date_start))

return redirect("event_detail",event_id=event.id)

这将打印event.date_start.hour:6event.date_start.tzinfo:Etc/GMT+2is_aware:True。然后,在保存对象并打印小时后,立即进行调整,它重定向event_detail视图,非常简单:

def event_detail(request,event_id):
    event = get_object_or_404(Event,id=event_id)
    print("event.date_start.hour:%s" % event.date_start.hour)
    print("event.date_start.tzinfo:%s" % event.date_start.tzinfo)
    ...

它会打印event.date_start.hour:8event.date_start.tzinfo:UTC。 (它已用UTC替换了tz信息)我不明白为什么。我用清晰的tz_info保存对象。请注意,我是在保存对象后的一小时内打印出来的,然后在另一个视图中检索到它后的一小时。相差两个小时,这与用户选择的时区(GMT + 2)有关。为什么是这样?哪种方法是保存此数据的最佳方法

用户在表单中提交“ 6:00 AM” +“ GMT + 2”,然后稍后当我想在事件详细信息html({{ event.date_start|date:"h:i A" }})中显示时间时,它显示“ 8:00 AM” “。

解决方法

我假设您正在使用PostgreSQL来保存时区感知时间戳。

重要的是要理解(与名称和流行的看法相反),PostgreSQL不会保存时区感知时间戳的时区。这只是一种告诉PostgreSQL该值不在本地时间,而是知道时区的方法。

然后PostgreSQL将其转换为UTC并进行存储。如果原始时区很重要,则需要将其单独存储。

有关该主题的更多信息:https://www.postgresqltutorial.com/postgresql-timestamp/

存储此数据的最佳方法是单独的一列(通常称为timezone)。我使用https://pypi.org/project/django-timezone-field/

然后使用activate时区(https://docs.djangoproject.com/en/3.1/ref/utils/#django.utils.timezone.activate)或使用localtimehttps://docs.djangoproject.com/en/3.1/ref/utils/#django.utils.timezone.localtime)实用程序功能。

,

根据Django docs

“启用时区支持后,Django将DateTime信息存储在数据库中的UTC中。将数据存储在数据库中的UTC中仍然是一种好习惯。主要原因是夏令时(DST)。” >

因此可以按预期将UTC格式的DateTime保存在数据库中。

现在,继续您的要求。为了在用于保存的时区中显示时间,您需要在数据库中添加一列以存储时区信息。

在检索DateTime时,请使用存储在数据库中的tzinfo将其转换回所需的时区。

这是正确的做法。希望这可以帮助您更好地理解。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...