[Pillola] DATE/TIME e MySQL 4.1.x
PARTE SECONDA
In questa seconda parte vedremo le nuove funzionalita' temporali di questo rilascio.
Ci sono veramente tante novita' che semplificheranno, e di molto, la gestione della
data/ora. Ma ricordiamoci che le seguenti query non sono compatibili con le versioni
di MySQL precedenti la 4.1.x
ADDTIME(espressione_temporale, tempo_da_addizionare)
SUBTIME(espressione_temporale, tempo_da_sottrarre)
Queste due funzioni provvedono ad addizionare / sottrarre porzioni di tempo da un
DATETIME, oppure da un altro valore TIME. Se si passano valori non congruenti la
risposta sara' NULL.
codice:
SELECT addtime('23:12:10','02:20:10') as somma, subtime('01:12:10','15:12:10') as diff;
=> somma = 25:32:20 diff = -14:00:00
SELECT addtime('2005-01-12 23:12:10','02:20:10') as somma,
subtime('2005-01-12 01:12:10','15:12:10') as diff
=> somma = 2005-01-13 01:32:20 diff = 2005-01-11 10:00:00
Quindi il primo argomento di ADDTIME accetta un valore DATETIME "yyyy-mm-dd hh:mm:ss"
oppure un valore TIME "hh:mm:ss", mentre il secondo argomento di ADDTIME accetta
solo un valore TIME "hh:mm:ss"
Se tentate di sommare/sottrarre DATA e TIME in questo modo: ('2005-01-12', '12:01:20')
non riceverete un NULL, ma un risultato errato e fantasioso.
DATEDIFF(espressione_temporale, espressione_temporale)
Strabella nuova funzione.... Dato due date (sic!) rende il numero dei giorni che
intercorrono. Anche qui valori non corretti daranno NULL come risultato.
codice:
$data_nascita = '1769-08-15'; // nascita di Napoleone
$query = mysql_query("select DATEDIFF(NOW(),'$data_nascita')");
$res = mysql_fetch_row($query);
echo "
RISULTATO -> $res[0]";
RISULTATO -> 86118 // (al 28 maggio 2005).
E cosi sappiamo quanto giorni avrebbe Napoleone al 28/05/2005.
Notare l'uso delle apici. Per campi, funzioni e costanti non ci vogliono.
TIMEDIFF(espressione_temporale, espressione_temporale)
Cugina della precedente questa funzione rende la differenza in hh:mm:ss tra due orari.
Accetta valori anche incompleti, con la seguente logica: se si immette una sola
cifra questa viene considerata come "secondi", Se le cifre sono due (es.: 12:35)
vengono considerate come hh:mm. Attenzione quindi all'impostazione degli argomenti.
Vediamo un po' di esempi:
codice:
select TIMEDIFF('23:35:30', '10:10:10') RISULTATO -> 13:25:20
select TIMEDIFF('23:35:30', '10:10') RISULTATO -> 13:25:30
select TIMEDIFF('23:35:30', '10') RISULTATO -> 23:35:20
select TIMEDIFF('23:35', '10:10:10') RISULTATO -> 13:24:50
select TIMEDIFF('23:35', '10:10') RISULTATO -> 13:25:00
select TIMEDIFF('35', '10') RISULTATO -> 00:00:25
select TIMEDIFF('30', '10:10:50') RISULTATO -> -10:10:20
Un risultato inatteso e' invece l'utilizzo di questa funzione con un valore DATETIME
negli argomenti. Viene trasformata in ore minuti secondi la differenza tra due
espressioni temporali:
codice:
select TIMEDIFF('2004-12-31 23:59:59', '2004-01-01 00:00:00') RISULTATO -> 8783:59:59
ecco il totale numero delle ore:min:sec di un anno bisestile.
select TIMEDIFF('2005-12-31 23:59:59', '2005-01-01 00:00:00') RISULTATO -> 8759:59:59
ed ecco quelle di un anno non bisesto.
select TIMEDIFF(NOW(), '2005-01-01 00:00:00'); RISULTATO -> 3541:55:23
differenza tra NOW() e l'inizio anno.... in ore:mm:ss
Oppure utilizzare TIMEDIFF nella clausola WHERE per un DELETE o un UPDATE....
Supponiamo che nel campo dataora ci sia il TIMESTAMP di immissione del dato,
e che sia, per esempio, l'inizio di una sessione su DB.
codice:
DELETE tabella WHERE TIMEDIFF(now(), dataora) >= '24:00:00'
UPDATE tabella set stato = 'scaduto' WHERE TIMEDIFF(now(), dataora) >= '24:00:00'
In questi casi verranno cancellati o aggiornati i dati presenti da piu' di 24 ore.
DATE(espressione temporale)
TIME(espressione temporale)
Queste due nuove funzioni potranno creare confusione per via delle omonime funzioni
PHP che hanno tutt'altra resa di dato. Queste due di MySQL estraggono rispettivamente
le rispettive porzioni di data e orario da un DATETIME oppure NULL se l'argomento
passato non e' valido.
codice:
SELECT date(NOW()) as data , time(NOW()) as ora
-> data 2005-01-12 - ora 14:17:22 // data ora corrente.
MAKEDATE(anno, giorno dell'anno)
MAKETIME(ora, minuti, secondi)
MAKEDATE rende la data che risulta dalla combinazione dell'anno e del numero del
giorno nell'anno. i valori devono essere degli INTERI. E' il naturale complemento
di DAYOFYEAR. Questa funzione rende NULL se il giorno dell'anno e' negativo oppure 0,
mentre se il numero e' superiore agli effettivi giorni dell'anno ... continua
nell'anno successivo.
codice:
SELECT MAKEDATE(2005, 250) RISULTATO -> 2005-09-07
SELECT MAKEDATE(2005, 250 + 200) RISULTATO -> 2006-03-26
MAKETIME vuole tre argomenti INTERI pure loro (senza apici). Non fa la somma, ma si
limita a controllare che i valori siano nel range ammesso dal formato campo TIME ed
assembla l'orario in formato hh:mm:ss
Anche se per le ore pare non abbia limiti (anche il frm TIME), i minuti e secondi
invece sono da 00 a 59
codice:
SELECT MAKETIME(123, 25 , 20) RISULTATO -> 123:25:20
DAY
Sinonimo di DAYOFMONTH rende il numero del giorno di una data. Se la data e' MULLA
risolvera' l'argomento come NULL.
LAST_DAY
Questa funzione prende un data e rende la data corrispondente all'ultimo giorno del
mese considerato nella data passata come argomento. Se la data passata non e'
valida rendera' NULL.
MICROSECOND
Qui la funzione si limita ad estrapolare i microsecondi passati con una data ma,
come gia' detto, non ad estrarre i microsecondi da una funzione.
codice:
mysql> SELECT microsecond ('2005-05-23 10:12:30.912399');
+--------------------------------------------+
| microsecond ('2005-05-24 14:12:30.912399') |
+--------------------------------------------+
| 912399 |
+--------------------------------------------+
1 row in set (0.00 sec)
WEEKOFYEAR(date)
Calcola la settimana dell'anno in un range 1 - 53. Si unisce ad altre due funzioni
preesistenti: WEEK(date) - YEARWEEK(date) a cui rimandiamo per il confronto nella
"pillola" precedente. http://forum.html.it/forum/showthrea...hreadid=459634
La prima settimana dell'anno, per questa funzione, e' quella in cui cade il primo lunedi'
oppure con altra valutazione, la settimana completa che contiene il giorno 4 gennaio.
codice:
mysql> SELECT WEEKOFYEAR('2005-01-02'), WEEKOFYEAR('2005-01-03');
+--------------------------+--------------------------+
| WEEKOFYEAR('2005-01-02') | WEEKOFYEAR('2005-01-03') |
+--------------------------+--------------------------+
| 53 | 1 |
+--------------------------+--------------------------+
1 row in set (0.00 sec)
STR_TO_DATE
Bella nuova funzione. E l'opposto di DATE_FORMAT. Da una stringa abbiamo ora
la facile possibilita' di ricavare una data. Il formato ricevuto sara' quello
di mysql e cioe' yyyy-mm-dd hh:mm:ss. I due parametri da passare sono:
il primo la data in formato stringa. La seconda che indichi come sono posizionati
i valori all'interno della stringa. I valori ammessi sono gli stessi di quelli
ammessi per DATE_FORMAT a cui si aggiunge ora "%f" per i microsecondi.
codice:
mysql> select str_to_date( '24/05/05 14.10.30' , '%d/%m/%y %H.%i.%s');
+---------------------------------------------------------+
| str_to_date( '24/05/05 14.10.30' , '%d/%m/%y %H.%i.%s') |
+---------------------------------------------------------+
| 2005-05-24 14:10:30 |
+---------------------------------------------------------+
1 row in set (0.00 sec)
Come si puo' vedere nel primo parametro passiamo un valore che e' una stringa,
nel secondo la composizione della stringa.
Ancora un esempio....
codice:
mysql> select str_to_date( '05, 24-2005 14:10' , '%m, %d-%Y %i:%s');
+-------------------------------------------------------+
| str_to_date( '05, 24-2005 14:10' , '%m, %d-%Y %i:%s') |
+-------------------------------------------------------+
| 2005-05-24 00:14:10 |
+-------------------------------------------------------+
1 row in set (0.00 sec)
**************** ********************* ************************** *****************
Fermiamoci qui. Ma le novita' di MySQL 4.1.x e le funzioni temporali non sono terminate.
Ci sarebbero ancora i dettagli di TIMESTAMP, GET_FORMAT (i formati sono prelevati da MaxDb).
Tutta la serie UTC_* (UTC_DATE UTC_TIME, UTC_TIMESTAMP) che rendono il tempo UTC.
Poi ancora la gestione del TIME ZONE che e' complessa se non fosse altro che per
la carenza di documentazione, non ultimo il rischio di casino con altri applicativi
che utilizzano il TIME ZONE.
Ma rimandiamo a tempi piu' opportuni oppure a qualcuno di buona volonta' il loro
completamento. Alcuni link ...
http://dev.mysql.com/doc/mysql/en/datetime.html
http://dev.mysql.com/doc/mysql/en/da...culations.html
http://dev.mysql.com/doc/mysql/en/da...functions.html
Alla prossima...