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(000$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(000,  $arr_fine[1],  $arr_fine[0],  $arr_fine[2]) - mktime(000$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

 

 



settore tecnico il sito di lorettabweb il Forum di sostegno
il forum il forum il forum