我在python中获取两个日期之间的天数差异存在问题。
我有以下代码块:
last_used = models.DateTimeField(default=datetime.now().date(), editable=False)
date_format = "%y-%m-%d"
a = datetime.strptime(str(datetime.now().date()), date_format)
b = datetime.strptime(str(last_used), date_format)
days_since_use = models.IntegerField(default=(b-a).days, editable=False)
我尝试了%y-%m-%d和YYYY-MM-DD格式,但是都没有用。
ValueError: time data '2018-09-16' does not match format '%y-%m-%d'
有什么想法吗?
答案 0 :(得分:1)
具有世纪的 年(如2018
,而不是18
)用%Y
表示(所以大写Y
){{ 3}}。
格式为:
%Y-%m-%d
使用这种格式,datetime.strptime
函数将产生以下结果:
>>> datetime.strptime('2018-09-16', '%y-%m-%d')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.6/_strptime.py", line 565, in _strptime_datetime
tt, fraction = _strptime(data_string, format)
File "/usr/lib/python3.6/_strptime.py", line 362, in _strptime
(data_string, format))
ValueError: time data '2018-09-16' does not match format '%y-%m-%d'
>>> datetime.strptime('2018-09-16', '%Y-%m-%d')
datetime.datetime(2018, 9, 16, 0, 0)
关于ValueError
(请参阅评论部分)。这源于您在类级别执行命令式编程的事实,这首先是巨大的“代码味道”(不要这样做,除非您例如想将可变数量的方法附加到类上,甚至那么真的很糟糕)。强制性代码只会在类级别上一次执行:在定义类时,因此对于Django而言,这意味着您加载服务器。
如果您需要对模型的天数进行编码,则可以将其添加到.save()
函数中:
class SomeModel(models.Model):
last_used = models.DateTimeField(default=datetime.now().date(), editable=False)
days_since_use = models.IntegerField(default=0, editable=False)
def save(self, *args, **kwargs):
self.days_since_use = (self.last_used.date() - datetime.now().date()).days
super(SomeModel, self).save(*args, **kwargs)
请注意,.save(..)
可以绕开。此外,该字段不将始终包含自该特定日期以来的天数,而仅包含days_since_use
至上次保存之间的天数。如果您要计算发生某件事后的天数,最好使用属性代替:
code>class SomeModel(models.Model): last_used = models.DateTimeField(default=datetime.now().date(), editable=False) @property def days_since_use(self): return (self.last_used.date() - datetime.now().date()).days
答案 1 :(得分:1)
我认为您不需要使用strptime
:
class A(models.Model):
last_used = models.DateTimeField(default=datetime.datetime.now(), editable=False)
obj = A().save()
a = datetime.datetime.now()
b = obj.last_used
difference = a-b # it gives datetime.timedelta object, and make sure that timedelta works only with datetime objects, so you can not use it with dates
# if you want to use with dates first convert them into datetime, then do manipulation and save.
然后您可以使用models.DurationField()
进行保存