【问题标题】:How to validate that a string is a valid date in Python如何验证字符串是否是 Python 中的有效日期
【发布时间】:2018-10-17 19:23:34
【问题描述】:

我在 Django 中有一个模型,它有两个 DateField,但有时它们会从前端收到错误的日期,例如“20196-10-23”。即使它实际上可能是一个有效日期(疯狂但合法),python 也不允许比较两个日期,因为这个错误:TypeError: '>=' not supported between instances of 'datetime.date' and 'str',所以我想使用clean() 方法来验证两个日期是否有效那些,但我总是把日期弄错,即使它们是正确的。

这是clean()方法的代码:

def clean(self, *args, **kwargs):
        try:
            Reservation.objects.get(booking=self.booking)
        except:
            pass
        else:
            raise CustomValidation(_('Booking already exists.'), 'booking', status_code=status.HTTP_400_BAD_REQUEST)

        print("{}/{}".format(self.arrival_date, self.departure_date))

        try:
            datetime.strptime(self.arrival_date, "%Y-%m-%d")
        except:
            raise CustomValidation(_('Arrival date must be a valid date.'), 'arrival_date', status_code=status.HTTP_400_BAD_REQUEST)

        if self.arrival_date >= self.departure_date:
            raise CustomValidation(_('Departure date must be later than Arrival date.'), 'departure_date', status_code=status.HTTP_400_BAD_REQUEST)
        elif self.arrival_date <= timezone.datetime.now().date():
            if self.id == None:
                raise CustomValidation(_('Arrival date must be later than today.'), 'arrival_date', status_code=status.HTTP_400_BAD_REQUEST)

        if self.status == 'CONFIRMED' and self.confirmation is None:
            raise CustomValidation(_('Must provide a confirmation number.'), 'confirmation', status_code=status.HTTP_400_BAD_REQUEST)

我总是遇到异常,即使日期正确。

【问题讨论】:

  • 错误可能发生在if self.arrival_date &gt;= self.departure_date: 线上,所以它告诉你departure_date 是一个字符串,而不是到达日期。这些数据是如何输入的?使用表单可能会更好。
  • 它总是以相同的方式输入,但是当日期是一个疯狂的日期(在本例中为'20196-11-17')时,python 将其视为字符串。
  • 是否也应该针对像arrival_date 这样的有效日期格式验证department_date 吗?
  • 是的,应该,但我还没有添加。

标签: python django


【解决方案1】:

虽然 20196 年在概念上是有效的年份,但 Python 不允许这样做。我试过这个...

import datetime
from datetime import date

def clean(arrival_date):
    return date(*map(int, arrival_date.split("-")))

print(clean("20196-10-23"))
# ValueError: year is out of range

...发现实际上有一个用于 Python 日期的硬编码 maximum year value of 9999

因此,虽然您可以通过各种方式在技术上验证格式,但您将无法使用内置的 datetime 模块处理这样的日期。

【讨论】:

    【解决方案2】:

    我通常首先将两个日期都设置为datetime.strptime()

    try:
        #get the dates 
        my_date_time_1 = self.cleaned_data['date_1']
        my_date_time_2 = self.cleaned_data['date_2']
        #set the datetime
        my_date_time_1 = datetime.strptime(my_date_time_1, '%Y-%m-%d %H:%M:%S')
        my_date_time_2 = datetime.strptime(my_date_time_2, '%Y-%m-%d %H:%M:%S')
    except:
        raise forms.ValidationError(u'Wrong Date Format')    
    
    
    #and then compare dates
    if my_date_time_1 >= my_date_time_2:
            raise forms.ValidationError(u'Please check the dates')
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-11-15
      • 1970-01-01
      • 1970-01-01
      • 2021-01-26
      • 2013-03-04
      • 2021-05-10
      • 1970-01-01
      相关资源
      最近更新 更多