Operazioni su date ed orari
Gli argomenti di questa pagina
- Definizione e sintassi della funzione PHP strtotime()
- Regole da adottare con la funzione PHP strtotime()
- Aggiungere o togliere del tempo alle date
- Calcolo orario lavorativo
|
Definizione e sintassi della funzione PHP strtotime()
La funzione strtotime() cerca di convertire in timestamp una stringa che rappresenta una data.
La sintassi è la seguente:
strtotime(time,now);
Se, come secondo parametro, viene indicato un timestamp viene restituito un valore rispetto a questo, altrimenti viene restituito il valore rispetto al timestamp corrente.
Alcune parole chiavi da indicare negli argomenti della funzione PHP strtotime() sono:
sec, second, min, minute, hour, day, month, year
Regole da adottare con la funzione PHP strtotime()
Prima di iniziare facciamo alcune considerazioni su alcune regole da tener presente.
Nell'esempio qui sotto mostrato uso alcuni formati di date indicati come:
- mm gg aaaa
- aaaa mm gg
- gg mm aaaa
Come separatore uso un trattino ( - ) o una barra inclinata ( / )
Nei due gruppi di date che rispettano questi parametri uso:
- nel primo gruppo le date coi giorni superiori a 12, quindi facilmente interpretabili, qualunque sia il loro formato.
- nel secondo gruppo le date coi giorni da 1 a 12, quindi interpretabili solo da chi le scrive.
Nel primo gruppo vediamo che alcune di queste date non restituiscono il timestamp e che alcune altre restituiscono il timestamp. Il fallimento della richiesta dipende dal formato e/o dal carattere separatore usato tra le varie parti delle date. Eseguendo il test per le date che restituiscono il timestamp notiamo che la data restituita è quella da noi attesa, qualsiasi sia la notazione usata.
Nel secondo gruppo viene eseguita la stessa sequenza usata nel primo con la differenza che il giorno è compreso tra 1 e 12. In alcuni casi la lettura delle date può risultare ambigua ed altrettanto ambiguamente vengono interpretate dall'interprete PHP. Per questo motivo il timestamp viene restituito per tutte le date ma la loro correttezza dipende solo dalla notazione usata.
Questo viene evidenziato da quel che ci viene restituito dai test eseguiti. Infatti notiamo che i test 2 e 5 (gli stessi che nel primo gruppo non restituiscono il timestamp) non restituiscono la data attesa ma coi giorni e mesi invertiti.
Per questi motivi se si intende usare la funzione PHP strtotime():
- se si lavora con date in stile americano m/d/y è da usare il separatore barra (/)
- se si lavora con date in stile europeo d-m-y è da usare il separatore trattino (-) o punto (.)
- se si lavora con date in formato y m d il separatore è indifferente.
1
2
3
4
5
6
7
8
9
|
<?php $mia_data = "23-02-2013"; $mio_strtotime = strtotime($mia_data); $test = date("d/m/Y", $mio_strtotime); echo $mia_data . "<br />\n"; echo $mio_strtotime . "<br />\n"; echo $test . "<br />\n"; ?>
|
23-02-2013
1361574000
23/02/2013
|
Con giorno sup a 12 |
Formato |
Data |
strtotime |
test |
1 - mm gg aaaa |
02/23/2013 |
1361574000 |
23/02/2013 |
2 - mm gg aaaa |
02-23-2013 |
|
01/01/1970 |
3 - aaaa mm gg |
2013/02/23 |
1361574000 |
23/02/2013 |
4 - aaaa mm gg |
2013-02-23 |
1361574000 |
23/02/2013 |
5 - gg mm aaaa |
23/02/2013 |
|
01/01/1970 |
6 - gg mm aaaa |
23-02-2013 |
1361574000 |
23/02/2013 |
con giorno ambiguo |
Formato |
Data |
strtotime |
test |
1 - mm gg aaaa |
02/10/2013 |
1360450800 |
10/02/2013 |
2 - mm gg aaaa |
02-10-2013 |
1380664800 |
02/10/2013 |
3 - aaaa mm gg |
2013/02/10 |
1360450800 |
10/02/2013 |
4 - aaaa mm gg |
2013-02-10 |
1360450800 |
10/02/2013 |
5 - gg mm aaaa |
10/02/2013 |
1380664800 |
02/10/2013 |
6 - gg mm aaaa |
10-02-2013 |
1360450800 |
10/02/2013 |
|
Aggiungere o togliere del tempo alle date
Qui sotto vengono eseguiti alcuni semplici calcoli sulle date usando la funzione PHP strtotime().
La notazione usata è gg/mm/aaaa. Per questo motivo, per quanto detto sopra, prima di estrarre il timestamp, vengono cambiati i caratteri separatori con la funzione php str_replace() sostituendo la barra inclinata ( / ) col trattino ( - ).
Per il primo esempio non viene attuata questa tecnica perchè con l'istruzione
$cur_date_add_month = date('d/m/Y',strtotime(" + 2 month"));
si lavora direttamente col timestamp della data corrente.
- Viene creata la data corrente (solo per la stampa a video).
- Vengono aggiunti due mesi alla data corrente.
- Vengono aggiunti 3 giorni e 4 ore ad una data qualsiasi usando la stessa data convertita in un formato adeguato con la funzione PHP str_replace().
- Vengono aggiunti 10 giorni e 2 mesi ad una data qualsiasi usando la stessa data convertita in un formato adeguato con la funzione PHP str_replace().
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
|
<?php // aggiunge 2 mesi alla data odierna $oggi = date("d/m/Y"); $cur_date_add_month = date('d/m/Y',strtotime(" + 2 month")); // ================================================= // vengono aggiunti 3 giorni e 4 ore ad una data $data_1 = "21/03/2005 17:30:22"; $timestamp = strtotime(str_replace('/', '-', $data_1)); $data_add_days_hours = date('d/m/Y H:i:s', strtotime ("+3 days 4 hours", $timestamp)); // ================================================= // aggiunge 10 giorni e 2 mesi ad una data $data_2 = "21-03-2014 08_30:25"; $timestamp_2 = strtotime(str_replace('/', '-', $data_2)); $num_giorni = 10; $data_add_days_month = date('d/m/Y H:i:s', strtotime ("+ " . $num_giorni . " days 2 month", $timestamp_2)); // ================================================= // stampa delle elaborazioni echo "Il caso più semplice<br />\n"; echo "Prima manipolazione: alla data odierna vengono aggiunti due mesi<br />\n"; echo $oggi . ": Data corrente<br />\n"; echo $cur_date_add_month . "<hr />\n"; echo "Seconda manipolazione; vengono aggiunti 3 giorni e 4 ore ad una data<br />\n"; echo $data_1 . ": Data in esame<br />\n"; echo $data_add_days_hours . "<hr />\n"; echo "Terza manipolazione: vengono aggiunti " . $num_giorni . " giorni e 2 mesi ad una data<br />\n"; echo $data_2 . ": Data in esame<br />\n"; echo $data_add_days_month . "<hr />\n"; ?>
|
Il caso più semplice
Prima manipolazione: alla data odierna vengono aggiunti due mesi
29/05/2022: Data corrente
29/07/2022
Seconda manipolazione; vengono aggiunti 3 giorni e 4 ore ad una data
21/03/2005 17:30:22: Data in esame
24/03/2005 21:30:22
Terza manipolazione: vengono aggiunti 10 giorni e 2 mesi ad una data
21-03-2014 08_30:25: Data in esame
11/03/1970 01:00:00
Un altro esempio per calcolare 90 giorni dalla data corrente.
1
2
3
4
5
6
|
<?php echo "Un esempio di una data a 90 giorni da quella corrente<br />\n"; $t_stamp = (strtotime("+90 days") . "<br>"); echo date('d/m/Y') . "<br />\n"; echo date("d/m/Y",$t_stamp) . "<br />\n"; ?>
|
Un esempio di una data a 90 giorni da quella corrente
29/05/2022
27/08/2022
Calcolo orario lavorativo
Questa è una piccola utility per calcolare le ore lavorative. Nei calcoli è compreso il calcolo su orari a cavallo della mezzanotte.
Il calcolo si effettua sui timestamp ottenuto con la funzione PHP strtotime() sull'orario finale e quello iniziale. Questo semplice calcolo permette senza ulteriori complicazioni di calcolo di restituire anche un valore per orari che sono a cavallo della mezzanotte.
Esempio 1: il più semplice
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<?php $start1 = "6:00"; $end1 = "14:20"; $start2 = "14:00"; $end2 = "21:55"; $start3 = "21:55"; $end3 = "6:05"; echo $start1 . " - " . $end1 . " -> "; echo date("H.i", strtotime($end1) - strtotime($start1) - 3600) . " ore lavorate<br />\n"; echo $start2 . " - " . $end2 . " -> "; echo date("H.i", strtotime($end2) - strtotime($start2) - 3600) . " ore lavorate<br />\n"; echo $start3 . " - " . $end3 . " -> "; echo date("H.i", strtotime($end3) - strtotime($start3) - 3600) . " ore lavorate<br />\n"; ?>
|
6:00 - 14:20 -> 08.20 ore lavorate
14:00 - 21:55 -> 07.55 ore lavorate
21:55 - 6:05 -> 08.10 ore lavorate
Esempio 2: il più preciso.
In questo caso, visto che le istruzioni da usare sono abbastanza corpose è consigliabile usare una funzione personale per separare le istruzioni per il calcolo e quelle che servono allo script.
La funzione restituisce, a seconda della differenza di tempo, un valore o una serie di valori che vanno dai soli secondi ai giorni, ore, minuti, secondi.
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
35
36
37
38
39
|
<?php function date_diff_calc($start, $end="NOW") { $sdate = strtotime($start); $edate = strtotime($end); $time = $edate - $sdate; if($time>=0 && $time<=59) { // Seconds $timeshift = $time.' seconds '; } elseif($time>=60 && $time<=3599) { // Minutes + Seconds $pmin = ($edate - $sdate) / 60; $premin = explode('.', $pmin); $presec = $pmin-$premin[0]; $sec = $presec*60; $timeshift = $premin[0].' min '.round($sec,0).' sec '; } elseif($time>=3600 && $time<=86399) { // Hours + Minutes $phour = ($edate - $sdate) / 3600; $prehour = explode('.',$phour); $premin = $phour-$prehour[0]; $min = explode('.',$premin*60); $presec = '0.'.$min[1]; $sec = $presec*60; $timeshift = $prehour[0].' ore '.$min[0].' min '.round($sec,0).' sec '; } elseif($time>=86400) { // Days + Hours + Minutes $pday = ($edate - $sdate) / 86400; $preday = explode('.',$pday); $phour = $pday-$preday[0]; $prehour = explode('.',$phour*24); $premin = ($phour*24)-$prehour[0]; $min = explode('.',$premin*60); $presec = '0.'.$min[1]; $sec = $presec*60; $timeshift = $preday[0].' gg '.$prehour[0].' ore '.$min[0].' min '.round($sec,0).' sec '; } return $timeshift; } ?>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<?php // per chiamare la funzione date_diff_calc() $start_date_1 = "01-08-2010 20:58:21"; $end_date_1 = "02-08-2010 07:10:30"; $start_date_2 = "02-08-2010 06:57:15"; $end_date_2 = "02-08-2010 14:11:00"; $start_date_3 = "02-08-2010 13:57:10"; $end_date_3 = "02-08-2010 13:58:05"; $start_date_4 = "02-08-2013 13:57:25"; $end_date_4 = date("d-m-Y H:i:s");
echo $start_date_1 . " - " . $end_date_1 . " => " . date_diff_calc($start_date_1, $end_date_1) . "<br />\n"; echo $start_date_2 . " - " . $end_date_2 . " => " . date_diff_calc($start_date_2, $end_date_2) . "<br />\n"; echo $start_date_3 . " - " . $end_date_3 . " => " . date_diff_calc($start_date_3, $end_date_3) . "<br />\n"; echo $start_date_4 . " - " . $end_date_4 . " => " . date_diff_calc($start_date_4) . "<br />\n"; ?>
|
01-08-2010 20:58:21 - 02-08-2010 07:10:30 => 10 ore 12 min 9 sec
02-08-2010 06:57:15 - 02-08-2010 14:11:00 => 7 ore 13 min 45 sec
02-08-2010 13:57:10 - 02-08-2010 13:58:05 => 55 seconds
02-08-2013 13:57:25 - 29-05-2022 12:40:59 => 3221 gg 22 ore 43 min 34 sec