alla ricerca del tempo peduto

mercoledì 23 aprile 2008

Da sempre la dimensione tempo ha affascinato e perseguitato l'uomo fornendogli la scusa per innumeroveli riflessioni e speculazioni filosofiche e fisiche.

Il concetto è vasto e sicuramente complesso, sia che si insegua una sua rigorosa definizione, sia che si tenti semplicemente di descriverlo.
"Se non mi chiedono cosa sia il tempo lo so, ma se me lo chiedono non lo so" cosi diceva S. Agostino.
Non parliamo del cercare di misurarlo, o confrontarlo...
Ed è proprio qui che entra in gioco la tecnologia (nel mio caso JavaTM!!) a pasticciare e complicare tutto, e non parlo solo dell'inaccuratezza dei chip RTC.

Qualche domanda semplice? Quanto dura un secondo? Un minuto o un'ora?
Quanto dura un giorno? Quanti giorni ci sono tra due date??
Soffermiamoci su quest'ultima questione.
Come calcolare la distanza tra due date?
Quanti giorni passano tra la mezzanotte del 31 Dicembre 2007 ed la mezzanotte del 23 Aprile 2008 ve lo dico io: 31+29+31+23=114, ma come li calcolo?
Qualcuno sghignazza pensando alla soluzione ovvia e banale...
basta dividere la differenza delle date in millisecondi con i millisecondi di un giorno



java.util.Date lateDate, earlyDate;
int deltaDays = (lateDate.getTime()-earlyDate.getTime())/MILLSECS_PER_DAY;

Semplice per quanto sbagliato!!
Si perchè utilizzando quella formula si ottiene 113!
Noo... ma allora c'è un bug nella java.util.Date?!!
Non proprio il bug è nel nostro calendario, infatti non tutti i giorni sono di 24 ore, no non sono impazzito, pensate alla Primavera e all’entrata in vigore dell’ora legale, in quel giorno si perde un'ora (si è un giorno da 23 ore!!), che si riacquista in autunno con una giornata da 25 ore.
Ma allora come si fa? Semplice si usa quello che il jdk offre ovvero il GregorianCalendar e il TimeZone, con il giusto aggiustamento dell'offset dovuto al cambio dell'ora legale.

java.util.GregorianCalendar start =new java.util.GregorianCalendar();
start.setTime(lateDate);
java.util.GregorianCalendar end =new java.util.GregorianCalendar();
end.setTime(earlyDate);
long endL = end.getTimeInMillis() + end.getTimeZone().getOffset( end.getTimeInMillis() );
long startL = start.getTimeInMillis() + start.getTimeZone().getOffset( start.getTimeInMillis() );
return (endL - startL) / MILLISECS_PER_DAY;


Ovviamente la soluzione ovvia e banale, funziona in tutti i casi in cui non si inciampi nel cambiamento dell'ora, ma io non la userei...

Illuminante la lettura di The Best of Dates, The Worst Of Dates e questi articoli al cui autore vanno i miei più sentiti ringraziamenti.

Pubblicato da Fabio inamoR il 4/23/2008 09:34:00 PM  

3 commenti:

Sei un pazzo...
E lo sai quale è la cosa grave? Che ti ho capito!!! I pazzi vanno sempre in coppia.
Un saluto

 

Quanto c'ho penato anche io...
Nel nostro caso dovevamo contare i minuti di ogni giorno e, se ci sono giorni da 24 ore, ci sono anche altri da 23 e 25...

E poi c'era anche la questione del luogo...
Cosa succederebbe se il codice venisse eseguito in Patagonia???
Ecco due semplici righe che m'hanno salvato pareccchio...

TimeZone tz = TimeZone.getTimeZone("Europe/Rome");
tz.inDaylightTime(day);

 

di default il Calendar si prende il TimeZone del tuo Locale (che di default è quello del sistema operativo ).... ;)
comunque nel mio caso gira sul server quindi conta il TimeZone ed il Locale del server

 

Posta un commento