2013-06-01 15 views
63

Ho un metodo python che accetta un input di data come una stringa.Come convalido un formato di stringa di data in python?

Come si aggiunge una convalida per assicurarsi che la stringa di data passata al metodo sia in ffg. Formato:

'YYYY-MM-DD' 

se non lo è, il metodo dovrebbe alzare una sorta di errore

+2

Potrebbe essere più Pythonic (chiedere perdono, non è permesso) non controllare a tutti, e prendere le eventuali eccezioni risultanti che si verificano. – Thomas

+0

Correlati: [In python, come verificare se una data è valida?] (Http://stackoverflow.com/q/9987818/55075) – kenorb

risposta

101
>>> import datetime 
>>> def validate(date_text): 
    try: 
     datetime.datetime.strptime(date_text, '%Y-%m-%d') 
    except ValueError: 
     raise ValueError("Incorrect data format, should be YYYY-MM-DD") 


>>> validate('2003-12-23') 
>>> validate('2003-12-32') 

Traceback (most recent call last): 
    File "<pyshell#20>", line 1, in <module> 
    validate('2003-12-32') 
    File "<pyshell#18>", line 5, in validate 
    raise ValueError("Incorrect data format, should be YYYY-MM-DD") 
ValueError: Incorrect data format, should be YYYY-MM-DD 
+0

C'è un modo per farlo senza provare/eccetto? Python tende a rallentare significativamente quando un'eccezione viene sollevata e catturata. – chiffa

+1

@chiffa È possibile associare un'espressione regolare al formato della data, ma non è consigliabile perché è meno affidabile e le eccezioni sono più chiare. Sei sicuro che la convalida della data sia il collo di bottiglia? – jamylak

+0

Non proprio, quindi alla fine racchiuderemo solo il costrutto - tranne il costrutto in una funzione. Sono sorpreso che non ci sia una funzione di convalida che restituisce bool che attiverà il lancio di eccezione nella libreria datetime. – chiffa

34

La biblioteca Python dateutil è stato progettato per questo (e molto altro). Lo convertirà automaticamente in un oggetto datetime e aumenterà un ValueError se non è possibile.

Per fare un esempio:

>>> from dateutil.parser import parse 
>>> parse("2003-09-25") 
datetime.datetime(2003, 9, 25, 0, 0) 

Questo solleva una ValueError se la data non è formattata correttamente:

>>> parse("2003-09-251") 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/Users/jacinda/envs/dod-backend-dev/lib/python2.7/site-packages/dateutil/parser.py", line 720, in parse 
    return DEFAULTPARSER.parse(timestr, **kwargs) 
    File "/Users/jacinda/envs/dod-backend-dev/lib/python2.7/site-packages/dateutil/parser.py", line 317, in parse 
    ret = default.replace(**repl) 
ValueError: day is out of range for month 

dateutil è anche estremamente utile se si inizia a dover analizzare altri formati in futuro , poiché è in grado di gestire i formati più noti in modo intelligente e consente di modificare le specifiche: dateutil parsing examples.

Gestisce anche i fusi orari se necessario.

aggiornamento sulla base dei commenti: parse accetta anche la parola argomento dayfirst che controlla se il giorno o il mese si prevede di venire prima se una data è ambiguo. Questo valore è impostato su False. Per esempio.

>>> parse('11/12/2001') 
>>> datetime.datetime(2001, 11, 12, 0, 0) # Nov 12 
>>> parse('11/12/2001', dayfirst=True) 
>>> datetime.datetime(2001, 12, 11, 0, 0) # Dec 11 
+0

può accettare troppo, ad es., 'parse ('13/12/2001 ')' è "13 Dec" ma 'parse ('11/12/2001')' è "12 Nov" (il primo risultato suggerirebbe "11 Dec" qui). – jfs

+0

'parse' richiede effettivamente un argomento di parola chiave' dayfirst' che consente di controllarlo. 'parse ('11/12/2001 ', dayfirst = True)' restituirà "11 dic." L'impostazione predefinita di dateutil è 'dayfirst = False' – Jacinda

+0

manca il punto in cui' datetutil.parser.parse() 'accetta troppi formati temporali (potresti trovare altri esempi con input ambigui). Se si desidera * verificare * che il proprio input sia nel formato AAAA-MM-GG, la funzione 'parse()' è lo strumento sbagliato. – jfs

11
from datetime import datetime 

datetime.strptime(date_string, "%Y-%m-%d") 

..si solleva ValueError se riceve un formato incompatibile.

..se si hanno a che fare con date e ore (nel senso di oggetti datetime, al contrario di unix timestamp float), è una buona idea esaminare il modulo pytz, e per storage/db, archivia tutto in UTC.

+2

Sei stato più veloce, lo avrei pubblicato da solo (http://ideone.com/vuxDDf). Upvote. – Tadeck

+0

.. l'ho visto subito dopo che è stato pubblicato, e capita di aver lavorato con oggetti datetime oggi. –

6

Penso che la funzione completa di convalida dovrebbe essere simile a questo:

from datetime import datetime 

def validate(date_text): 
    try: 
     if date_text != datetime.strptime(date_text, "%Y-%m-%d").strftime('%Y-%m-%d'): 
      raise ValueError 
     return True 
    except ValueError: 
     return False 

esecuzione solo

datetime.strptime(date_text, "%Y-%m-%d") 

non è sufficiente perché strptime metodo non controlla che il mese e il giorno della il mese sono numeri decimali con zero cifre. Ad esempio

datetime.strptime("2016-5-3", '%Y-%m-%d') 

sarà eseguito senza errori.

+1

"Sei tecnicamente corretto - il miglior tipo di corretto." Dovevo assicurarmi di ciò nelle mie corde. – delrocco

0

Questo è il modo più semplice:

date = datetime.now() 
date = date.strftime('%Y-%m-%d_%H-%M-%S.jpg') 
+0

Formato data errato per le domande poste –

Problemi correlati