0

I have a model in Django that has two DateFields, but sometimes they receive wrong dates from the front-end, like '20196-10-23'. Even when it might actually be a valid date (crazy, but legit), python doesn't allow to compare both dates due to this error: TypeError: '>=' not supported between instances of 'datetime.date' and 'str', so I want to use clean() method to verify that both dates are valid ones, but I always get dates wrong, even when they are correct.

This is the code for clean() method:

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)

I always get an exception, even when the date is correct.

HuLu ViCa
  • 5,077
  • 10
  • 43
  • 93
  • https://stackoverflow.com/questions/3642892/calculating-if-date-is-in-start-future-or-present-in-python Might be useful – Tim Oct 17 '18 at 19:25
  • The error is presumably happening on the line `if self.arrival_date >= self.departure_date:`, so it's telling you that `departure_date` is a string, not arrival_date. How is this data getting entered? It would probably be better to use a form. – Daniel Roseman Oct 17 '18 at 19:33
  • It always get entered the same way, but when the date is a crazy one ('20196-11-17', in this case), python treats it as a string. – HuLu ViCa Oct 17 '18 at 19:44
  • Should departure_date also be validated for a valid date format like arrival_date is? – ocobacho Oct 17 '18 at 20:10
  • Yes, it should, but I haven't added that yet. – HuLu ViCa Oct 17 '18 at 20:35

2 Answers2

1

While 20196 is conceptually a valid year, Python won't allow it. I tried this...

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

...and found out there's actually a hard-coded maximum year value of 9999 for Python dates.

So while you could technically validate the format in various ways, you won't be able to handle dates like this with the built-in datetime module.

kungphu
  • 4,592
  • 3
  • 28
  • 37
0

I usually first set both dates as 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')
WayBehind
  • 1,607
  • 3
  • 39
  • 58