PHP  »  Articoli  »  Programmazione Php 

Date in PHP: come gestirle

di: Ermanno Ancona     07 Aprile 2005

Quando ci vuole precisione

Come ultima funzione prendiamo in considerazione microtime() che fornisce lo unix timestamp più i microsecondi espresso nella forma "microsecondi secondi". Un classico esempio di utilizzo lo si trova nel calcolo del tempo di esecuzione di uno script. Una funzione simile alla seguente permette di ottenere un timestamp più preciso con l'aggiunta dei microsecondi:

<?php
 function get_microtime()
 {
 //spezza il microtime in due variabili
 list($misec,$sec) = explode(' ', microtime());
 // aggiunge microsecondi e secondi
 return ((float)$misec + (float)$sec);
 }
 $start = get_microtime();
 /*
 codice da eseguire
 */
 $stop = get_microtime();
 echo 'tempo di esecuzione: '. ($stop-$start);
?>

Per ottenere una stima attendibile conviene comunque ripetere l'esecuzione dello script più volte e calcolarne la media. Altro esempio di applicazione è l'inizializzazione del generatore di numeri pseudocasuali per ottenere un numero arbitrario:

<?php
 srand(get_microtime());
 $unique_number = rand();
?>

Si noti che a partire versione 4.2.0 di PHP l'argomento di srand() è opzionale, e per default viene impostato un valore casuale.

Costruiamo un calendario

Veniamo finalmente all'utilizzo pratico di alcune delle funzioni precedentemente illustrate. Per la costruzione del calendario ci avvarremo di un'altra funzione cal_days_in_month() disponibile dalla versione 4.1.0 di PHP e che fa' parte delle cosiddette "funzioni di calendario". Tale funzione fornisce, in breve, il numero di giorni per un fissato calendario, mese e anno.

Il primo argomento specifica il calendario cui fare riferimento, quello che noi adottiamo dal 1582 è il gregoriano, CAL_GREGORIAN, in onore di papa Gregorio XIII che sostituì il calendario giuliano, CAL_JULIAN, introdotto da Giulio Cesare nel 45 a.C.. Purtroppo, per aumentare la confusione, non tutti i paesi europei adottarono tale calendario immediatamente....il discorso ci porterebbe lontano concentriamoci sul nostro codice:

<?php
 function print_calendar($month="",$year="")
{
 // impostiamo la data attuale
 $now = getdate(time());
 // controlliamo mese e anno passati
 if ( empty($month) OR empty($year) OR !is_numeric($month) OR !is_numeric($year) OR !@checkdate($month,1,$year) )
 {
 $month = $now['mon'];
 $year = $now['year'];
 }
 // unix timestamp del primo giorno
 // del mese e dell'anno ricevuti
 $time = mktime(0,0,0, $month, 1, $year);
 // genera l'array con le informazioni
 $date = getdate($time);
 // giorni totali per il mese e anno
 $day_total = cal_days_in_month(CAL_GREGORIAN, $date['mon'], $date['year']);
 //stampa mese e anno in oggetto
 //in italiano come intestazione
 setlocale(LC_TIME,"it_IT");
 $mese_anno = strftime('%B',$date[0]). " " .$year;
 echo "<table><tr><td colspan=\"7\"><strong>$mese_anno</strong></td></tr>\n";
 // stampa le abbreviazioni dei giorni della settimana
 echo "<tr><td>Do</td><td>Lu</td><td>Ma</td><td>Me</td> <td>Gi</td><td>Ve</td><td>Sa</td></tr>\n";
 for ($i = 0; $i < 6; $i++)
 {
 echo '<tr>';
 for ($j = 1; $j <= 7; $j++)
 {
 $day_number = $j + $i*7 - $date['wday'];
 //stampa la cella con il giorno
 echo '<td';
 if ($day_number > 0 AND $day_number <= $day_total)
 {
 // borda di rosso se è oggi
 if ($day_number == $now['mday'] AND $month == $now['mon'] AND $year == $now['year'])
 {
 echo " style=\"border: 1px solid #cc0000;\" ";
 }
 echo ">$day_number";
 }
 else
 {
 //stampa una cella vuota se non esiste il giorno
 echo '> ';
 }
 echo '</td>';
 }
 echo "</tr>\n";
 if ($day_number >= $day_total AND $i != 6)
 break;
 }
 echo "</table>\n";
 }
?>

Il codice precedente risulta volutamente non ottimizzato per maggiore comprensibilità. La prima parte controlla che i parametri passati siano accettabili altrimenti utilizza il mese e l'anno correnti. Si è fatto ricorso alla funzione is_numeric che controlla se i valori sono numeri o stringhe numeriche per poter utilizzare immediatamente dati provenienti da un form. Successivamente viene stampata l'intestazione del calendario, ricorrendo a setlocale() per l'italiano, con mese ed anno e l'abbreviazione dei giorni della settimana.

Il ciclo for più esterno for($i = 0; $i < 6; $i++) serve a costruire le righe del calendario che possono essere al massimo 6 nel caso il primo giorno del mese sia sabato ed il mese abbia più di 29 giorni.

Il ciclo più interno calcola e stampa il numero del giorno $day_number = $j + $i*7 - $date['wday']. Ogni riga riporta 7 giorni, per ognuna si parte da 1 più il numero di riga moltiplicato per 7. Questo sarebbe sufficiente se il primo giorno del mese fosse sempre domenica, ma non è così. Al valore va' quindi sottratto il numero del giorno della settimana da cui parte il mese che costituisce una sorta di "shift".

Se richiamiamo la funzione senza parametri, print_calendar(), otteremo il calendario del mese e giorno correnti. Se volessimo, invece, il calendario di giugno 2007 dovremo scrivere print_calendar(6,2007) ottenendo il seguente risultato:

giugno 2007
Do Lu Ma Me Gi Ve Sa
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

Conclusioni

Come al solito scegliendo la funzione giusta al momento giusto PHP ci facilita il lavoro anche se gestire date e tempo risulta, in alcuni casi, abbastanza delicato. I risultati ottenuti talora dipendono dalle caratteristiche del sistema su cui gira PHP, lo si è accennato per il timestamp o per la funzione setlocale().

A complicare le cose contribuiscono, ad esempio, le differenze di fuso orario delle varie zone geografiche, i vari calendari, il DST. Se il nostro server si trova a Londra è probabile che segua il WET, Western European Time, coincidente con il GMT, Greenwich Mean Time (orario di riferimento) o con GMT + 1 durante il British Summer Time. Mentre noi utilizziamo il Central European Time, CET, pari a GMT + 1 o GMT + 2 se consideriamo l'ora legale.

Queste considerazioni finali non vogliono disarmare, ma solo esortare a prestare molta attenzione quando il quadro che abbiamo di fronte presenta complessità non sottovalutabili. In ultimo riporto che gli esempi dell'articolo sono testati su Linux Fedora Core 3, PHP 4.3.10, Apache 2.0.52.

Guide PHP

Guida Yii Framework

Come creare applicazioni Web in modo semplice e veloce con il...

Guida Zend Framework

Diventate professionisti dello sviluppo Web. Zend Framework è lo...

Guida Applicazioni Facebook con PHP

Come realizzare un'applicazione per Facebook. Dalle basi della...

Altre guide

Newsletter @PHP

Ogni lunedì, direttamente nella tua e-mail: script, articoli, guide e tutorial su PHP, MySQL e Apache.

Iscriviti alla newsletter

Altre newsletter

Corsi in aula

Corso PHP per Webmaster

11 Giugno 2012 a Milano
Disponibilità: 7 Posti

Corso Google AdWords Base

25 Giugno 2012 a Milano
Disponibilità: 7 Posti

Corso Google AdWords Base

05 Giugno 2012 a Roma
Disponibilità: 7 Posti