En Python, ¿cómo verificar si una fecha es válida?

Estoy construyendo una especie de aplicación web de calendario.

He configurado el siguiente formulario en HTML

 Year ("yyyy"):  Month ("mm"):  Day ("dd"):  Hour ("hh"):  Description:    

La entrada del usuario se envía en un servidor cherrypy

Me pregunto si hay una manera de verificar si la fecha ingresada por el usuario es válida.

Obviamente, podría escribir muchas declaraciones if, pero ¿hay alguna función integrada que pueda verificar esto?

Gracias

Podrías intentar hacer

 import datetime datetime.datetime(year=year,month=month,day=day,hour=hour) 

eso eliminará cosas como meses> 12, horas> 23, días bisiestos inexistentes (mes = 2 tiene un máximo de 28 en años sin salto, 29 de lo contrario, otros meses tienen un máximo de 30 o 31 días) (lanza la excepción ValueError en caso de error)

También podrías intentar compararlo con algunos límites superiores / inferiores de cordura. ex.:

 datetime.date(year=2000, month=1,day=1) < datetime.datetime(year=year,month=month,day=day,hour=hour) <= datetime.datetime.now() 

Los límites de cordura superior e inferior relevantes dependen de sus necesidades.

edición: recuerde que esto no controla ciertos tiempos de datos que pueden no ser válidos para su aplicación (cumpleaños mínimo, días festivos, fuera de las horas de operación, etc.)

Puede intentar usar datetime y manejar las excepciones para decidir una fecha válida / no válida: Ejemplo: http://codepad.org/XRSYeIJJ

 import datetime correctDate = None try: newDate = datetime.datetime(2008,11,42) correctDate = True except ValueError: correctDate = False print(str(correctDate)) 

Usar datetime

p.ej.

 >>> from datetime import datetime >>> print datetime(2008,12,2) 2008-12-02 00:00:00 >>> print datetime(2008,13,2) Traceback (most recent call last): File "", line 1, in  print datetime(2008,13,2) ValueError: month must be in 1..12 

Aquí hay una solución usando el tiempo.

  tiempo de importación
 def is_date_valid (año, mes, día):
     this_date = '% d /% d /% d'% (mes, día, año)
     tratar:
         time.strptime (this_date, '% m /% d /% Y')
     excepto ValueError:
         falso retorno
     más:
         volver verdadero

Puede intentar usar datetime y manejar las excepciones para decidir una fecha válida / no válida:

 import datetime def check_date(year, month, day): correctDate = None try: newDate = datetime.datetime(year, month, day) correctDate = True except ValueError: correctDate = False return correctDate #handles obvious problems print(str(check_date(2008,11,42))) #handles leap days print(str(check_date(2016,2,29))) print(str(check_date(2017,2,29))) #handles also standard month length print(str(check_date(2016,3,31))) print(str(check_date(2016,4,31))) 

da

 False True False True False 

Esta es una mejora de la respuesta de DhruvPathak y tiene más sentido como una edición, pero se rechazó porque ” Esta edición tenía la intención de dirigirse al autor de la publicación y no tiene sentido como una edición. Debería haber sido escrita como un comentario o un comentario. respuesta ” .

 y = int(input("Year: ")) m = int(input("Month: ")) d = int(input("Day: ")) if 0 <= y and 0 < m < 13 and 0 < d < 32: #Check whether date is under limit. if y % 4 == 0: # Every 4 year "Leap" year occures so checking... if m == 2: # In "Leap" year February has 29 days if d < 30: print("") else: print("") elif m == 2: # But if it's not "Leap" year February will have 28 days if d < 29: print("") else: print("") elif y % 4 != 0 and m != 2: # Otherwise print "Correct" print("") else: print("") 

La pregunta asume que la solución sin bibliotecas implica “una gran cantidad de declaraciones if”, pero no:

 def is_valid_date(year, month, day): day_count_for_month = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] if year%4==0 and (year%100 != 0 or year%400==0): day_count_for_month[2] = 29 return (1 <= month <= 12 and 1 <= day <= day_count_for_month[month]) 

Por lo tanto, aquí está mi solución hacky para corregir las fechas no válidas proporcionadas Esto supone que el usuario está enviando desde un formulario html genérico que proporciona los días 1-31 como opciones. El problema principal son los usuarios que proporcionan un día que no existe para el mes (ex 31 de septiembre)

 def sane_date(year, month, day): # Calculate the last date of the given month nextmonth = datetime.date(year, month, 1) + datetime.timedelta(days=35) lastday = nextmonth.replace(day=1) - datetime.timedelta(days=1) return datetime.date(year, month, min(day, lastday.day)) class tests(unittest.TestCase): def test_sane_date(self): """ Test our sane_date() method""" self.assertEquals(sane_date(2000,9,31), datetime.date(2000,9,30)) self.assertEquals(sane_date(2000,2,31), datetime.date(2000,2,29)) self.assertEquals(sane_date(2000,1,15), datetime.date(2000,1,15))