Calcoli sui mesi
Gli argomenti di questa pagina
- Ultimo giorno del mese con una funzione personale
- Giorni mancanti a fine mese
- Giorni trascorsi tra due date
|
Ultimo giorno del mese con una funzione personale
In PHP è facile ottenere il numero dei giorni per ciascun mese dell'anno usando la funzione PHP date().
La sintassi è semplice: date(format,timestamp)
Normalmente l'argomento "format" è rappresentato da una stringa con tre caratteri: d m Y.
Questi tre caratteri indicano che vogliamo vedere la data indicata dal timestamp. Ma abbiamo a disposizione una vasta gamma di caratteri da usare nell'argomento "format".
Il carattere che in questa pagina ci interessa è la lettera "t".
In questo esempio riciclo, leggermente modificata, la funzione presentata all'apertura di questo sotto-settore. Uso questa funzione solo per avere la possibilità di agire con qualsiasi formato di data. E' ovvio che si potrebbero avere risultati non attesi per le date che hanno il giorno ed il mese inferiori o uguali a 12. In questi casi occorre verificare l'origine della data e stabilire se si tratta di data in formato europeo (gg/mm/aaaa) o di data o UNIX (mm/gg/aaaa). Questo caso lo discuteremo più in basso.
In questa funzione:
- divido la data in tutte le sue parti usando la funzione PHP preg_split() ed un pattern che usa tutti i possibili caratteri delimitatori usati per una data
- controllo se il primo elemento è di quattro caratteri, tipico formato usato in SQL
- verifico se la data è corretta usando la funzione PHP checkdate()
- creo la nuova data in formato UNIX usando le parti di data esplose precedentemente
- se la data non è in formato SQL cerco di controllarne il formato cambiandone il formato in UNIX
- finite le verifiche sulla data estraggo il mese ed i numeri di giorni usando la funzione strtotime() sulla nuova data in formato UNIX
- La funzione restituisce in una matrice il mese ed il numero di giorni per il mese se le verifiche sulla data sono positive, oppure FALSE se le verifiche sono fallite
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
|
<?php function fine_mese($data){ $data_parts = preg_split('/[-\.\/: ]/', $data); if (strlen($data_parts[0]) == 4) { if(checkdate($data_parts[1], $data_parts[2], $data_parts[0])){ $new_data = $data_parts[1] . "/" . $data_parts[2] . "/" . $data_parts[0]; } else { return FALSE; } } else { if(checkdate($data_parts[0], $data_parts[1], $data_parts[2]) && checkdate($data_parts[1], $data_parts[0], $data_parts[2])){ $new_data = $data_parts[1] . "/" . $data_parts[0] . "/" . $data_parts[2]; } elseif(checkdate($data_parts[0], $data_parts[1], $data_parts[2])){ $new_data = $data_parts[0] . "/" . $data_parts[1] . "/" . $data_parts[2]; } elseif(checkdate($data_parts[1], $data_parts[0], $data_parts[2])){ $new_data = $data_parts[1] . "/" . $data_parts[0] . "/" . $data_parts[2]; } else { return FALSE; } } if ($new_data) { $mese = date("m",strtotime($new_data)); $dies = date("t",strtotime($new_data)); return array ($mese, $dies); } else { return FALSE; } } ?>
|
Questo è il frammento di codice che, per ogni data nell'elenco, richiama la funzione e ne visualizza i risultati.
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
31
32
33
34
|
<?php $data_1 = "24/01/2001"; $data_2 = "31/02/2001"; $data_3 = "07/02/2001"; $data_4 = "01/07/2001"; $data_5 = "08/15/2001"; $data_6 = "15/09/2001"; $data_7 = "2001/02/22"; $data_8 = "2001/02/30"; $fine_mese_1 = fine_mese($data_1); $fine_mese_2 = fine_mese($data_2); $fine_mese_3 = fine_mese($data_3); $fine_mese_4 = fine_mese($data_4); $fine_mese_5 = fine_mese($data_5); $fine_mese_6 = fine_mese($data_6); $fine_mese_7 = fine_mese($data_7); $fine_mese_8 = fine_mese($data_8); echo "Per " . $data_1 . ": "; echo (!$fine_mese_1) ? "Data non valida<br />\n" : "Mese: " . $fine_mese_1[0] . " - giorni: " . $fine_mese_1[1] . "<br />\n"; echo "Per " . $data_2 . ": "; echo (!$fine_mese_2) ? "Data non valida<br />\n" : "Mese: " . $fine_mese_2[0] . " - giorni: " . $fine_mese_2[1] . "<br />\n"; echo "Per " . $data_3 . ": "; echo (!$fine_mese_3) ? "Data non valida<br />\n" : "Mese: " . $fine_mese_3[0] . " - giorni: " . $fine_mese_3[1] . "<br />\n"; echo "Per " . $data_4 . ": "; echo (!$fine_mese_4) ? "Data non valida<br />\n" : "Mese: " . $fine_mese_4[0] . " - giorni: " . $fine_mese_4[1] . "<br />\n"; echo "Per " . $data_5 . ": "; echo (!$fine_mese_5) ? "Data non valida<br />\n" : "Mese: " . $fine_mese_5[0] . " - giorni: " . $fine_mese_5[1] . "<br />\n"; echo "Per " . $data_6 . ": "; echo (!$fine_mese_6) ? "Data non valida<br />\n" : "Mese: " . $fine_mese_6[0] . " - giorni: " . $fine_mese_6[1] . "<br />\n"; echo "Per " . $data_7 . ": "; echo (!$fine_mese_7) ? "Data non valida<br />\n" : "Mese: " . $fine_mese_7[0] . " - giorni: " . $fine_mese_7[1] . "<br />\n"; echo "Per " . $data_8 . ": "; echo (!$fine_mese_8) ? "Data non valida<br />\n" : "Mese: " . $fine_mese_8[0] . " - giorni: " . $fine_mese_8[1] . "<br />\n"; ?>
|
Questo è quel che lo script qui sopra produce:
Per 24/01/2001: Mese: 01 - giorni: 31
Per 31/02/2001: Data non valida
Per 07/02/2001: Mese: 02 - giorni: 28
Per 01/07/2001: Mese: 07 - giorni: 31
Per 08/15/2001: Mese: 08 - giorni: 31
Per 15/09/2001: Mese: 09 - giorni: 30
Per 2001/02/22: Mese: 02 - giorni: 28
Per 2001/02/30: Data non valida
Per le date che hanno il giorno ed il mese inferiori o uguali a 12 è possibile usare uno dei due esempi mostrati qui sotto.
Per le date in formato europeo, prima di lavorare col suo timestamp, la converto prima in formato UNIX, quindi posso estrarne il mese ed il suo numero di giorni.
Per le date in formato UNIX, eseguo le due operazioni direttamente dal suo timestamp.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<?php $data = "07/02/2001"; // Esempio con data in formato europeo $data_parts = preg_split('/[-\.\/: ]/', $data); $new_data = $data_parts[1] . "/" . $data_parts[0] . "/" . $data_parts[2]; $mese = date("m",strtotime($new_data)); $dies = date("t",strtotime($new_data)); echo "Esempio di data: " . $data . "<br />\n"; echo "Esempio con data in formato europeo: gg/mm/aaaa<br />\n"; echo "Mese: " . $mese . " - giorni: " . $dies . "<br />\n"; // Esempio con data in formato UNIX $mese = date("m",strtotime($data)); $dies = date("t",strtotime($data)); echo "Esempio con data in formato UNIX: mm/gg/aaaa<br />\n"; echo "Mese: " . $mese . " - giorni: " . $dies . "<br />\n"; ?>
|
Esempio di data: 07/02/2001
Esempio con data in formato europeo: gg/mm/aaaa
Mese: 02 - giorni: 28
Esempio con data in formato UNIX: mm/gg/aaaa
Mese: 07 - giorni: 31
Giorni mancanti a fine mese
visto come ottenere il numero dei giorni del mese, ora possiamo vedere come calcolare i giorni mancanti alla fine del mese.
In questo esempio lavoro su due date:
- quella corrente che è la prima
- una data qualsiasi che è la seconda
Per la data corrente, una volta rilevati i due dati necessari al computo, si calcolano i giorni mancanti alla fine del mese
Per una data qualsiasi, il lavoro è leggermente più lungo:
estraggo i componenti della data per creare con essi il timestamp e quindi rilevo i due dati necessari al computo per calcolare i giorni mancanti alla fine del mese
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
|
<?php // Opzionali $cur_date = date("d/m/Y"); $mese = date ("m"); // rilevamento dati per il calcolo $giorni_del_mese = date ("t"); $giorno_attuale = date ("d"); echo "Per " . $cur_date . "<br />\n"; echo "Mese in esame: " . $mese . "<br />\n"; echo "Giorni del mese " . $giorni_del_mese . " - giorno in esame " . $giorno_attuale . "<br />\n"; // il calcolo da eseguire echo "Alla fine del mese mancano " . ($giorni_del_mese - $giorno_attuale) . " giorni<hr />\n"; // ================================= $qualsiasi_data = "18/02/2004"; list($giorno, $mese, $anno, $ora, $minuti, $secondi) = preg_split('/[-\.\/: ]/', $qualsiasi_data); $t_stamp = mktime(0, 0, 0, $mese, $giorno, $anno); $mese = date ("m", $t_stamp); // rilevamento dati per il calcolo $giorni_del_mese = date ("t", $t_stamp); $giorno_attuale = date ("d", $t_stamp); echo "Per " . $qualsiasi_data . "<br />\n"; echo "Mese in esame: " . $mese . "<br />\n"; echo "Giorni del mese " . $giorni_del_mese . " - giorno in esame " . $giorno_attuale . "<br />\n"; // il calcolo da eseguire echo "Alla fine del mese mancano " . ($giorni_del_mese - $giorno_attuale) . " giorni<br />\n"; ?>
|
Per 29/05/2022
Mese in esame: 05
Giorni del mese 31 - giorno in esame 29
Alla fine del mese mancano 2 giorni
Per 18/02/2004
Mese in esame: 02
Giorni del mese 29 - giorno in esame 18
Alla fine del mese mancano 11 giorni
Giorni trascorsi tra due date
Questa è un'altra attività che a volte può rivelarsi utile, cioè stabilire quanti giorni sono trascorsi tra due date.
Per calcolare i giorni trascorsi tra due date faccio alcuni esempi, fondamentalmente uguali, ma che adottano metodi leggermente differenti.
Primo esempio:
- divido le date nei loro vari componenti usando la funzione PHP preg_split() con una espressione regolare che valuta tutti i possibili caratteri separatori di una data
- calcolo il timestamp di ciascuna data con la funzione PHP mktime()
- calcolo la differenza tra i due timestamp e, se la differenza è negativa la rendo positiva eseguendo la moltiplicazione per -1
- quindi sul risultato ottenuto, eseguo tre divisioni (60, 60, 24) che equivale a dividerlo per 86400
- prima della stampa del risultato, questo va arrotondato con la funzione PHP round()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
<?php // numero giorni tra 2 date php $start = "11/06/2011"; $end = "11/07/2011"; $arrD1 = preg_split('/[-\.\/: ]/', $start); $arrD2 = preg_split('/[-\.\/: ]/', $end); $time1 = mktime(0,0,0,$arrD1[1],$arrD1[0],$arrD1[2]); $time2 = mktime(0,0,0,$arrD2[1],$arrD2[0],$arrD2[2]); $secDif = $time1-$time2; if ($secDif<0) { $secDif=$secDif*-1; } $minDif = $secDif / 60; $hourDif = $minDif / 60; $dayDif = $hourDif / 24; echo "Per le date " . $start . " - " . $end . "<br />\n"; echo round($dayDif) . " giorni trascorsi<br />\n"; ?>
|
Per le date 11/06/2011 - 11/07/2011
30 giorni trascorsi
Secondo esempio:
- divido le date nei loro vari componenti usando la funzione PHP preg_split() con una espressione regolare che valuta tutti i possibili caratteri separatori di una data
- calcolo la differenza tra i due timestamp creati al volo nello stesso calcolo
- anche qui uso la funzione PHP floor() per arrotondare la divisione per 60, 60, 24
1
2
3
4
5
6
7
8
9
10
11
|
<?php // numero giorni tra 2 date php $start = "11/06/2011"; $end = "21/07/2011"; $arr_partenza = preg_split('/[-\.\/: ]/', $start); $arr_fine = preg_split('/[-\.\/: ]/', $end); $date_diff = mktime(0, 0, 0, $arr_fine[1], $arr_fine[0], $arr_fine[2]) - mktime(0, 0, 0, $arr_partenza[1], $arr_partenza[0], $arr_partenza[2]); $date_diff = floor(($date_diff / 60 / 60 / 24)); echo "Per le date " . $start . " - " . $end . "<br />\n"; echo $date_diff . " giorni trascorsi<br />\n"; ?>
|
Per le date 11/06/2011 - 21/07/2011
40 giorni trascorsi
Terzo esempio:
- divido le date nei loro vari componenti usando la funzione PHP preg_split() con una espressione regolare che valuta tutti i possibili caratteri separatori di una data, ma in questo caso i componenti delle date vengono messi in altrettante variabili anzichè in una matrice
- Quindi eseguo il calcolo alla solita maniera
1
2
3
4
5
6
7
8
9
10
11
12
|
<?php // numero giorni tra 2 date php $start = "11/06/2011"; $end = "11/08/2011"; list($start_gg, $start_mm, $start_aa, $ora, $minuti, $secondi) = preg_split('/[-\.\/: ]/', $start); list($end_gg, $end_mm, $end_aa, $ora, $minuti, $secondi) = preg_split('/[-\.\/: ]/', $end); $data_partenza = mktime(0,0,0,$start_mm,$start_gg,$start_aa); $data_arrivo = mktime(0,0,0,$end_mm,$end_gg,$end_aa); $giorni = ($data_arrivo - $data_partenza)/86400; echo "Per le date " . $start . " - " . $end . "<br />\n"; echo $giorni . " giorni trascorsi<br />\n"; ?>
|
Per le date 11/06/2011 - 11/08/2011
61 giorni trascorsi
Quarto esempio:
- come il terzo esempio ma stavolta uso la data odierna
1
2
3
4
5
6
7
8
9
10
11
12
|
<?php // numero giorni tra 2 date php $start = "11/06/2013"; $end = date("d/m/Y"); list($start_gg, $start_mm, $start_aa, $ora, $minuti, $secondi) = preg_split('/[-\.\/: ]/', $start); list($end_gg, $end_mm, $end_aa, $ora, $minuti, $secondi) = preg_split('/[-\.\/: ]/', $end); $data_partenza = mktime(0,0,0,$start_mm,$start_gg,$start_aa); $data_arrivo = mktime(0,0,0,$end_mm,$end_gg,$end_aa); $giorni = ($data_arrivo - $data_partenza)/86400; echo "Per le date " . $start . " - " . $end . "<br />\n"; echo $giorni . " giorni trascorsi<br />\n"; ?>
|
Per le date 11/06/2013 - 29/05/2022
3274 giorni trascorsi