[Pillola] DATE/TIME e MySQL 4.1.x
PARTE PRIMA
Aggiornamento della Gestione DATE/TIME con MySQL 4.1.
La fonte di riferimento e' il manuale ufficiale MySQL. E' un aggiornamento
della documentazione su DATE/TIME in MySQL 4.1.7, quindi trattera' solo le modifiche
e le nuove prestazioni ripetto alla precedente pillola su DATE/TIME di cui non e'
sostitutiva ma di solo aggiornamento.
Tutte le query sono state testate e funzionanti su una suite composta da:
Apache 2.0.47 - PHP 4.3.10 - MySQL 4.1.8 - OS WIN 2000/XP-SP2.
Premessa: Poiche' modifiche ed aggiornamenti si sono susseguite man mano nei
vari rilasci della versione 4.1, prenderemo in considerazione la prima versione stabile
rilasciata, la 4.1.7 e superiore. Per le versioni precedenti alla 4.1.7 fate
riferimento al manuale.
Rif.: http://dev.mysql.com/doc/mysql/en/da...functions.html
MySQL 4.1 e la gestione dei campi formato DATE/TIME.
Vediamo quindi subito eventuali cambiamenti al formato dei campi data:
rif.: http://dev.mysql.com/doc/mysql/en/Da..._overview.html
YEAR
Registra l'anno e occupa un solo byte. I valori validi oscillano tra
il 1901 e il 2155. Uguale alla versione precedente.
rif.: http://dev.mysql.com/doc/mysql/en/YEAR.html
TIME
Registra ora : minuti : secondi. Il range ammesso va da -838 a 838 per le ore,
mentre per minuti e secondi da 00 a 59. Somma le ore percio' dope le 24 continuera'
con 25, 26, eccetera... Uguale alla versione precedente.
DATE
Il range ammesso e' da: '1000-01-01' a '9999-12-31'. Il campo viene memorizzato
come prima in YYYY-MM-DD e sono accettati sia formati numerici (es.: 20050101)
che formati stringa (es.: '2005/01/01'). Da sottolineare che il separatore puo'
essere qualunque, ma il dato andra' passato come stringa, cioe' tra apici.
Uguale alla versione precedente.
Rif. valido anche per DATETIME e TIMESTAMP: http://dev.mysql.com/doc/mysql/en/DATETIME.html
DATETIME
Il range ammesso e' il solito, da: 1000-01-01 00:00:00 al 9999-12-31 23:59:59.
Una nota avverte che le date iniziali del range potrebbero non essere valide in
un prossimo futuro. Chiaro che, essendo il Calendario Gregoriano introdotto nel 1582
da Papa Gregorio XII, il precedente Calendario Giuliano aveva una composizione
diversa e come tutte le date precedenti il 1582 queste sono da considerare solo
date approssimate. DATETIME resta comunque uguale alla versione precedente.
TIMESTAMP
Vediamo qui il primo dei cambiamenti sostanziali. Come gia' detto nella premessa
i cambiamenti sono avvenuti man mano con l'evolversi della release 4.1, chi fosse
interessato ai vari step, puo' riferirsi in dettaglio al manuale.
http://dev.mysql.com/doc/mysql/en/TIMESTAMP_4.1.html
Il campo TIMESTAMP ha ora una dimensione fissa ed e' NULL. La visualizzazione del
valore e' identica al formato DATETIME YYYY-MM-DD HH:MM:SS. Non si potra' piu'
quindi scegliere il numero dei digit da visualizzare. A differenza della versione 4.0
dove il campo TIMESTAMP ad essere automaticamente aggiornato (INSERT o UPDATE) era
obbligatoriamente il primo (nel caso di piu' campi TIMESTAMP), ora e' possibile
scegliere quale campo dichiarare auto-aggiornante. La scelta puo' essere fatta al
momento della creazione della tabella (CREATE TABLE) oppure successivamente con
ALTER TABLE, tenendo pero' presente che di campi auto-aggiornanti puo' essercene
uno solo e quindi volendolo cambiare, si deve prima togliere la caratteristica
di CURRENT_TIMESTAMP all'altro campo se presente.
Esempi equivalenti dal manuale:
codice:
CREATE TABLE t (
ts1 TIMESTAMP DEFAULT 0,
ts2 TIMESTAMP DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP);
CREATE TABLE t (
ts1 TIMESTAMP DEFAULT 0,
ts2 TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
DEFAULT CURRENT_TIMESTAMP);
Mentre per modificare con ALTER TABLE ho verificato:
codice:
ALTER TABLE t CHANGE ts2 ts2 TIMESTAMP
DEFAULT 0;
ALTER TABLE t CHANGE ts1 ts1 TIMESTAMP
DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP;
In questo modo si scambia il campo auto-aggiornante tra ts2 e ts1.
Altra cosa da tenere in considerazione e' il TIME-ZONE.
A partire dalla versione 4.1.3 e' possibile assegnare al server MySQL un TIME-ZONE
diverso da quello di sistema, per ogni client che si connette al database.
(Variabili "system time zone" e "time zone").
In merito precisiamo che:
CURRENT_DATE(), CURRENT_TIME(), CURRENT_TIMESTAMP(), FROM_UNIXTIME(), LOCALTIME(),
LOCALTIMESTAMP(), NOW(), SYSDATE() e UNIX_TIMESTAMP() rendono il valore del corrente
TIME-ZONE del client, mentre UTC_DATE(), UTC_TIME(), UTC_TIMESTAMP() rendono il
valore UTC. (UTC Universal Time Coordinate = GMT Greenwich Mean Time).
Quindi se nella tabella descritta in precedenza, assegnassimo al campo con DEFAULT 0
il valore estratto con UTC_TIMESTAMP troveremo l'ora UTC, mentre nell'altro auto-
aggiornante che ha CURRENT_TIMESTAMP() come default, troveremo l'ora locale (CET o CEST).
La variazione del TIME-ZONE e' piuttosto consistente per MySQL e sarebbe bene
trattarla a parte in modo piu' esaustivo. Anche perche' e' possibile introdurre
malfunzionamenti data/ora che potrebbero propagarsi anche ad altri applicativi.
rif.: http://dev.mysql.com/doc/mysql/en/Ti...e_support.html
FUNZIONI VARIATE.
Anche qui una dovuta premessa: Molti dei cambiamenti sono dovuti per avvicinarsi
alla compatibilita' con MaxDB. Per esempio l'introduzione dei microsecondi,
validi come sintassi, non gestiti nei campi del db ma solo da alcune funzioni...
Non riceverete un errore, ma solo un risultato zero. Il formato dei microsecondi
va da 000000 (sei zero) a 999999 (sei nove).
Gli esempi che seguono sono tratti da un articolo di Trudy Pelzer: Temporal
Functionality http://dev.mysql.com/tech-resources/.../4.1/time.html e dal
manuale: http://dev.mysql.com/doc/mysql/en/Da...functions.html
Tutti testati sulla suite predetta. Diamo ora un'occhiata alle poche funzioni variate.
ADDDATE - SUBDATE
Accettano ora un secondo e comodo parametro "numero_dei_giorni". Sara' quindi possibile
sommare o sottrarre rapidamente dei giorni da una data, che puo' essere esplicita,
da funzione, campo o variabile.
codice:
mysql> select adddate('2004-10-01',15), subdate('2004-10-01',15);
+--------------------------+--------------------------+
| adddate('2005-01-01',15) | subdate('2005-01-01',15) |
+--------------------------+--------------------------+
|2005-01-16 | 2004-12-17 |
+--------------------------+--------------------------+
1 row in set (0.20 sec)
Altro esempio: trovare i record con max 30 giorni di presenza:
codice:
SELECT * FROM table WHERE data BETWEEN SUBDATE(NOW(), 30) AND NOW()
Queste due funzioni si differenziano percio' dalle loro, in precedenza equivalenti,
DATE_ADD e DATE_SUB per la possibilita' di inserire un valore "giorno" senza ulteriori
istruzioni.
DATE_ADD - DATE_SUB
Continuano come in precedenza ed insieme alle due funzioni precedenti accettano ora
la costante dei microsecondi. I nuovi parametri sono: DAY_MICROSECOND,
HOUR_MICROSECOND, MINUTE_MICROSECOND, SECOND_MICROSECOND e MICROSECOND.
codice:
mysql> SELECT DATE_ADD('1992-12-31 23:59:59.000002',
INTERVAL '1.999999' SECOND_MICROSECOND) as msec;
+-----------------------------------+
| msec |
+-----------------------------------+
| 1993-01-01 00:00:01.000001 |
+-----------------------------------+
EXTRACT(intervallo_costante FROM espressione)
Funzione poco utilizzata ma utile per estrarre valori da una data/ora.
codice:
mysql> SELECT EXTRACT(YEAR_MONTH FROM NOW()) as anno_mese;
+------------+
| anno_mese |
+------------+
| 200501 |
+------------+
Utilizza tutte le possibili combinazioni di valori previste dalle costanti usate dalle
funzioni sopra descritte. (cfr. manuale)
DATE_FORMAT - TIME FORMAT
Anche queste funzioni ora hanno un nuovo valore nel formato stringa che producono:
'%f' che rende appunto i microsecondi.
Inutile provarci... rendera' sempre 000000. Pero' non vi dara' errore.
DATE_FORMAT ha finalmente il degno compare che fara' il suo esatto inverso.... cioe'
mentre DATE_FORMAT prende una data e rende una stringa a piacere, STR_TO_DATE prende
una stringa e rende una data. Fara' felice chi memorizza la data nel campo VARCHAR
nel formato gg/mm/aaaa. Ma lo vedremo piu' avanti trattando le numerose nuove funzioni.
Fine parte 1