如何确保保存在数据库中的UTC日期等于Django中指定时区的午夜

how to make sure that the UTC date saved in the database is equivalent to midnight in the specified timezone in Django

我想将数据库中的日期时间保存为特定用户的午夜。我将时区保存在我的用户对象上。但是,数据库一直将其保存为 UTC 午夜。下面是我正在使用的代码。

tz_obj = pytz.timezone(user.timezone)
start_date = tz_obj.normalize(date_obj.replace(day=1, hour=0, minute=0, second=0, microsecond=0))
end_date = tz_obj.normalize(date_obj.replace(day=calendar.monthrange(date_obj.year, date_obj.month)[1], hour=23, minute=59,
                                    second=59, microsecond=99999))
obj = MyObject.objects.create(start=start_date, end=end_date)

谁能告诉我如何确保数据库中保存的 UTC 日期等于指定时区的午夜。

更新 每个用户可能有不同的时区,因此在设置文件中设置时区并不能解决这个问题。

注意:如评论中所述,此方法不正确。我们需要在用户的时区中获取 date 对象,就像重复问题的答案一样。

因此,我们需要 datetime.now(tz).date(),而不是 date.today()


如果我答对了你的问题,你想将午夜存储在假定时区 +5:30 中,作为 UTC 中的 18:30?如果是这样的话,你可以这样做:

>>> from datetime import date, time, datetime
>>> naive_midnight = datetime.combine(date.today(), time())
>>> tz = pytz.timezone('Asia/Kolkata')
>>>
>>> # Attach local timezone to above naive datetime object
>>> midnight_user_timezone = tz.localize(naive_midnight)
>>> print midnigth_user_timezone
2015-12-15 00:00:00+05:30
>>>
>>> # Convert to UTC
>>> midnight_to_utc = midnight_user_timezone.astimezone(pytz.UTC)
>>> print midnigth_to_utc
2015-12-14 18:30:00+00:00

Django 有一个名为 make_aware 的函数,用于将时区原始日期时间对象转换为时区感知日期时间对象。

aware_date_obj = make_aware(date_obj, user.timezone)

由于日期时间对象已经 link 到正确的时区,您只需在 aware_date_obj 上使用 .replace(day=1, hour=0, minute=0, second=0, microsecond=0) 即可获得年初在指定的时区。

如果日期时间对象已经识别时区但不在正确的时区,您可以使用 astimezone 将其转换为正确的时区:

date_obj.astimezone(user.timezone)

然后您可以再次使用.replace功能。

最后,当Django在数据库中存储datetime对象时,时区信息会丢失。时间点仍然是正确的,但在从数据库加载后它将被 linked 为默认的 django 时区。然后您将不得不再次使用 astimezone 函数将其 link 到正确的时区。