关于python:Django DateTimeField的Django DST时间更改问题

Django DST Time change issue with django datetimefield

我在使用DateTimeField时在django应用程序中遇到问题,这主要是因为DST时间更改。

我在2015年10月30日(上个夏令时)创建了一个活动。
我创建了第一项活动的副本,该副本将于2015年11月6日(美国夏令时当天)

我应用了7天的timedelta,所以将天数更改为7+。 但是我几个小时都没有使用timedelta。

由于节省日光,因此减少了一个小时。 我不需要这个。 我只想有几个小时。 我怎样才能做到这一点。?

我尝试过此方法,但没有帮助我。

django应用程序中的DST时区问题

请看这个截图
enter image description here

我的models.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from django.db import models
from datetime import timedelta

class Event(models.Model):

    name = models.CharField(max_length=100)

    created = models.DateTimeField(auto_now_add=True)

    start_date = models.DateTimeField()

    def __unicode__(self):
        return self.name


    def copy_event(self, add_days=timedelta(days=7)):

        start_date = self.start_date + add_days
        name = self.name +' (copy)'
        new_event = Event(name = name,created = self.created,start_date=start_date,)

        new_event.save()

        return new_event


我在Django中创建重复事件时遇到了同样的问题,这是我发现的解决方案,它很干净而且到目前为止是可行的。在以下位置使用代码:

1
start_date = self.start_date + add_days

尝试:

1
start_date = self.start_date.replace(tzinfo=None) + add_days

它将self.start_date参数转换为原始日期时间,并允许增加天数而不考虑时区。我已经对它进行了广泛的测试,它既可以向前发展也可以向后退。

参考:在Python中将时区感知日期时间转换为本地时间


发现这是最好的解决方案

1
2
3
4
5
from django.utils.timezone import localtime

l = Event.objects.get(...)
time = localtime(l.time + timedelta(days=7))
time += localtime(l.time).dst() - time.dst()


USE_TZ=True开始,您始终要处理有意识的日期时间,这些时间代表精确的时间。通常,该时间点会根据当前时区不同地显示。有些时区具有DST,有些时区没有DST,因此通常无法存储日期时间,以便所有时区中的所有用户都可以看到所需的时钟时间(即与复制事件相同的时钟时间)。

我可以想到几个解决方法:

  • 如果是仅服务一个时区的情况(也就是说,当前时区始终是相同的),则可以在该时区中进行算术运算。

    1
    2
    from django.utils.timezone import localtime
    new_start_date = localtime(self.start_date) + add_days

    add_days的添加将始终使时钟时间保持不变(也就是说,它不考虑DST)。 new_start_date将转换为UTC并存储在UTC中,然后转换回所需的本地时间进行显示。

  • 您真正要代表的是特定日期的特定时钟时间,而不是确切的时间。因此,也许您根本不想使用已知的日期时间。一种选择是设置USE_TZ=False,但这是您可能不想进行的全局性,深远的更改。另一种选择是对该字段使用不同的表示形式。例如,您可以使用DateFieldTimeField代替DateTimeField