时间数据与格式 YYYY-MM-DD 不匹配

Key*_*ume 5 django django-rest-framework

我在获取 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)
Run Code Online (Sandbox Code Playgroud)

我尝试过 %y-%m-%d 和 YYYY-MM-DD 格式,但都不起作用。

ValueError: time data '2018-09-16' does not match format '%y-%m-%d'

有任何想法吗?

Wil*_*sem 6

每个文档中带有世纪的年份(如 in 2018, not )用(因此大写)18表示。%YY

格式如下:

%Y-%m-%d
Run Code Online (Sandbox Code Playgroud)

使用这种格式,该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)
Run Code Online (Sandbox Code Playgroud)

至于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)
Run Code Online (Sandbox Code Playgroud)

请注意,.save(..)然而可以被绕过。此外,该字段并不总是包含自该特定日期以来的天数,而仅包含自days_since_use上次保存以来的天数。如果您想计算某件事发生后的天数,最好使用属性:

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
Run Code Online (Sandbox Code Playgroud)