这里有些古怪我无法理解:
鉴于以下设置:
>>> from django.conf import settings
>>> settings.TIME_ZONE
'Europe/London'
>>> settings.USE_TZ
False
鉴于以下模型:
HALF_YEAR = timedelta(days=30*6)
class ProductManager(models.Manager):
def get_queryset(self):
from_date = datetime.now() - HALF_YEAR
return super(ProductManager, self).get_queryset().filter(start_date_time__gt=from_date)
class Product(models.Model):
product_number = models.CharField(max_length=45)
start_date_time = models.DateTimeField()
cover_renewal_date = models.DateField()
objects = ProductManager()
这给了我们数据库表:
shopapp=>\d shop_product
Column | Type | Modifiers
-----------------------+--------------------------+----------------------------------------------------------
id | integer | not null default nextval('shop_product_id_seq'::regclass)
product_number | character varying(45) | not null
start_date_time | timestamp with time zone | not null
shopapp=> show timezone;
TimeZone
----------
UTC
(1 row)
使用以下数据:
shopapp=> select product_number, start_date_time
from shop_product
where product_number in ('PN63145707', 'PN57284554', 'PN57291674', 'PN66177827');
product_number | start_date_time
---------------+------------------------
PN57284554 | 2013-04-05 00:00:00+00
PN57284554 | 2014-04-05 00:00:00+00
PN57284554 | 2015-04-05 00:00:00+00
PN57284554 | 2016-04-05 00:00:00+00
PN57284554 | 2017-04-05 00:00:00+00
PN57291674 | 2013-04-04 00:00:00+00
PN57291674 | 2014-04-04 00:00:00+00
PN57291674 | 2015-04-04 00:00:00+00
PN57291674 | 2016-04-04 00:00:00+00
PN57291674 | 2017-04-04 00:00:00+00
PN63145707 | 2015-03-25 00:00:00+00
PN63145707 | 2016-03-25 00:00:00+00
PN63145707 | 2017-03-25 00:00:00+00
PN66177827 | 2017-03-25 00:00:00+00
(14 rows)
但运行此代码:
now = datetime.now().date()
start_time = now - timedelta(days=1)
end_time = now + timedelta(days=14)
res = Product.objects.filter(start_date_time__range=(start_time, end_time), product_number__in=['PN63145707', 'PN57284554', 'PN57291674', 'PN66177827'])
for item in res:
print(item.product_number, str(item.start_date_time))
给我结果
(u'PN63145707', '2017-03-25 00:00:00')
(u'PN57284554', '2017-04-05 01:00:00')
(u'PN57291674', '2017-04-04 01:00:00')
(u'PN66177827', '2017-03-25 00:00:00')
看起来任何超出BST(3月26日)的start_date_time都显示时间为凌晨1点。如果USE_TZ设置为False,为什么会这样?
感谢。
版本: Django的1.10.4, postgresql psql(9.4.10,server 9.6.1)
修改: 当我在测试服务器上使用相同的设置运行相同的代码时,结果不一样:
In [20]: settings.TIME_ZONE
Out[20]: 'Europe/London'
In [21]: settings.USE_TZ
Out[21]: False
(u'PN63145707', '2017-03-25 00:00:00')
(u'PN66177827', '2017-03-25 00:00:00')
(u'PN57291674', '2017-04-04 00:00:00')
(u'PN57284554', '2017-04-05 00:00:00')
为什么这些记录没有像生产服务器上的值那样调整到欧洲/伦敦时区?
答案 0 :(得分:1)
您所看到的行为完全如documentation中所述。它是Django坚持使用postgresql timestamptz
而不是timestamp
的副产品。
在内部,Postgresql timestamptz
以UTC格式存储日期时间。查询时,它会返回转换为请求者时区的时间戳。
documentation注意到,当USE_TZ
设置为false
时,数据库连接时区将设置为TIMEZONE
(在您的情况下为欧洲/伦敦)。这将导致 Postgresql将存储的UTC时间戳转换为伦敦时间,然后再将它们提供给Django。
答案 1 :(得分:0)
including
返回当前的本地日期和时间,在您的情况下,它会返回生产服务器的日期和时间。您应该将其转换为您的特定时区datetime.now()
,或者您可以使用符合Europe/London
配置的django.utils.timezone.now
:
settings.py
请注意django.utils.timezone.now根据from django.utils import timezone
now = timezone.now().date()