Lavorare con le date in Php senza smadonnamenti

Appunti -> Php

php_logoUno degli incubi più grandi di ciascun programmatore è lavorare con le date. Aggiungere un anno ad una data, togliere due ore ad un certo giorno, contare quanti giorni passano tra due date, controllare quanti giorni porta giugno e se il 2009 è un anno bisestile sono solo alcuni dei drammi del povero programmatore di php.

Ci sono due tipi di approcci a questo problema; la scuola dei puristi vorrebbe che si lavorasse sempre con l'mktime, ovvero la funzione che restituisce il tempo in secondi partendo dalla famossissima mezzanotte in punto del 1 gennario 1970, lo UNIX Epoch. Questa opzione ha la brutta abitudine di creare problemi (con versioni di php inferiori alla 5.1.0) con date che includano anni precedenti al 1970 e successivi al 2038. Se si vuole seguire questa linea di pensiero si trasformano tutte le date in valori di mktime e si eseguono i dovuti calcoli.

Questo frammento di codice restituisce il numero di secondi dalla mezzanotte in punto del 1 gennario 1970 alla mezzanotte di oggi.


$sec = mktime(0, 0, 0, date('m'), date('d'), date('Y') );
// la sintassi completa del comando è questa:
int mktime ( int $hour, int $minute, int $second, int $month, int $day, int $year, int $is_dst= -1 )

Quindi, ad esempio, per calcolare la differenza tra due date calcoleremo lo Unix timestamp di entrambe, sottrarremo la più piccola dalla più grande e otterremo il numero di secondi di differenza che potremo poi ritrasformare con divisioni successive nell'unità che ci interessa (es /60 se ci interessano i minuti, /3600 se ci interessano le ore). Provate però voi ad immaginare la complessita di un codice scritto da zero che ti avverta che 61 secondi sono 1 minuti e 1 secondo e non circa 1.017 minuti. Ovvero: perchè dovrei scrivere delle funzioni elaborate piuttosto che sfruttare le funzioni esistenti del PHP?

Arriviamo quindi alla soluzione che mi appunto su questa pagina per poterla cercare velocemente quando mi occorrerà di nuovo: la funzione strtotime();
Questa funzione accetta il passaggio di due parametri di cui il secondo facoltativo: una stringa che indichi l'operazione da eseguire sulla data e uno Unix timestamp su cui effettuare l'operazione (se questo secondo parametro è omesso la funzione lavora con lo Unix timestamp restituito dal server al momento dell'esecuzione).

Se vogliamo quindi aggiungere un mese alle 16:34:00 19 febbraio 1980 e vogliamo in uscita una data nel formato gg-mm-aaaa dovremo scrivere:


$data = date( 'd-m-Y', strtotime( "+1 month", mktime( 16, 34, 00, 02, 19, 1980 ) ) );

Può sembrare un metodo forse più macchinoso, ma il tempo che si salva nell'usarla vale il breve apprendimento mnemonico che richiede.

Ultima chicca sull'argomento date. Avete mai dovuto scrivere una funzione per poter stampare una data del tipo "mercoledì 5 luglio 2009" partendo da una data del tipo "05-07-2009"? La cosa più veloce (e forse anche la più pulita) è utilizzare strftime(). Questa funzione accetta il passaggio di due parametri, di cui il secondo facoltativo: il primo una stringa che gli dica come deve restituire la data e il secondo il solito valore della data in Unix timestamp.

Questo è un esempio di utilizzo:


// IMPORTANTE: prima di utilizzare la funzione bisogna
// dire al PHP che vogliamo la data in italiano
// nel caso volessimo i nomi dei giorni
// della settimana o dei mesi
setlocale(LC_ALL, 'it_IT');

echo strftime( "%A %d %B %Y", mktime( 0, 0, 0, 7, 5, 2009 ) );

Può capitare che si renda necessario fare un utf8_encode della stringa che restituisce la funzione strftime perché non restituisce correttamente le lettere accentate dei giorni della settimana.

Per le evntuali personalizzazioni dei formati di uscita con tutte le relative opzioni date uno sguardo ai riferimenti qui sotto:
strtotime()
strftime()
setlocale()