Newsgroup: it.comp.java
Titolo: Giornate perse dietro alle Date

salve a tutti, poco giorni fa avevo postato delle lamentele su come operare
correttamente con le Date evitando di usare metodi deprecati e mi è stato
risposto di usare Calendar.
L'ho fatto e quando è giunto il momento di eseguire dei calcoli tra dati,
per esempio la cosa tipica che mi serve è: "Quanti giorni intercorrono tra 2
date diverse?", ho iniziato a fare i conti con i millisecondi. Esempio
Calendar p1 = Calendar.getInstance();
    p1.set(2002, 5, 18, 0, 0);
    Calendar p2 = Calendar.getInstance();
    p2.set(2002, 7, 13, 0, 0);
    java.sql.Date d1 = new java.sql.Date(p1.getTime().getTime());
    java.sql.Date d2 = new java.sql.Date(p2.getTime().getTime());
    long modulo = ((d2.getTime() - d1.getTime()) % 86400000L);
Essendo dei Calendar che specificano dei giorni INTERI (ovvero senza parte
oraria o per meglio dire che vale 00:00:00) mi aspetto che il modulo della
loro differenza sia 0
L'esempio sopra infatti restituisce 0 ma se provate con i mesi
2 e 4 otterrete 82800000
con 8 e 10 otterrete 3600000
Qual'è la spiegazione. E' per caso colpa di quel fo**utissimo "leap second"
di cui parla la documentazione di Date???
Bene dopo una giornata spesa a fare divisioni e moduli con i long resto
ancora col mio problema
Come fare i calcoli fra date??????
N.B: quella sopra è un'idea che mi è venuta a me, ma se qualcuno a qualcosa
di meglio da suggerire, al diavolo la soluzione dell'enigma (di solito ci
tengo a scoprire il perchè di queste "stranezze" ma dopo una giornata di
inca**ature come quella di oggi ho perso ogni interesse
Grazie e buona serata a tutti

 loro differenza sia 0
No, la divisone intera č 0.
(il modiulo lo usi per ottenere i giorni interi di
differenza, quando le date non sono a 00:00:00)
Calendar p1 = Calendar.getInstance();
p1.set(2002, 5, 18, 0, 0);
Calendar p2 = Calendar.getInstance();
p2.set(2002, 7, 13, 0, 0);
    long millisecgiorno1=p1.getTime().getTime()% 86400000L;
    long millisecgiorno2=p1.getTime().getTime()% 86400000L;
    long giornidifferenza =
(millisecgiorno2-millisecgiorno1)/86400000L;
CarloP.

 ha
scritto nel messaggio news:bgohl6$qpqju$1...@ID-104614.news.uni-berlin.de...


 (millisecgiorno2-millisecgiorno1)/86400000L;
Scusa Carlo, ma se d1 e d2 sono due java.util.date, cosa ci sarebbe di 
sbagliato in:
long nGiorni = ((d2.getTime() - d1.getTime()) / 86400000L)
Non mi pare che getTime è deprecata.

 Come fare i calcoli fra date??????
Su date e calendari si possono sostanzialmente fare due tipi di calcoli:
- determinare intervalli di tempo, cioe' calcolare quanto tempo
   e' passato tra due istanti temporali t0 e t1.
- sommare o sottrarre intervalli di tempo ad un istante t0
   per ottenere t1.
Per il primo tipo di calcolo (trovare l'intervallo di tempo
compreso tra t0 e t1) si utilizzano i Date, facendo le divisioni
delle differenze in millisecondi tra i due Date.
Ad esempio:
    Date d1 = ...;
    Date d2 = ...;
    long giorni = (d2.getTime()-d1.getTime())/(24*60*60*1000);
Per il secondo tipo di calcolo (aggiungere o togliere N giorni
ad una certa data) si usano i metodi add o roll (leggete la 
documentazione per capire la differenza tra i due) della classe
Calendar;
     Calendar c1 = ...;
     int giorni g = ...;
     c1.add(Calendar.DATE, g);
Infine un po' di conversioni:
   Per passare da Calendar a Date: c1.getTime()
   Per passare da Date a Calendar: c1.setTime(d1)
   Per passare da Date a millisecondi: d1.getTime()
   Per passare da millisecondi a Date: d1.setTime()
Di solito non si usa un Calendar a caso, ma si usa un particolare
Calendar scelto con Calendar.getInstance()
oppure si usa un GregorianCalendar.
- Dario

 ha scritto nel messaggio
news:MPG.1999f03c8...@news.fu-berlin.de...

Infatti non lo è, ma per fare l'operazione Andrea convertiva
il calendar in un Date con:
 java.sql.Date d1 = new
java.sql.Date(p1.getTime().getTime());
che è un'operazione inutile, visto che il getTime già lo
faceva.....
Se è possibile cerco di evitare di creare oggetti che non mi
siano indispensabili,
ma è solo una questione di abitudini.
CarloP

 > p2.set(2002, 7, 13, 0, 0);
Qui al posto di:
         long millisecgiorno1=p1.getTime().getTime()%
86400000L;
         long millisecgiorno2=p1.getTime().getTime()%
86400000L;
va:
         long
millisecgiorno1=p1.getTime().getTime()-(p1.getTime().getTime
()% 86400000L);
         long
millisecgiorno2=p2.getTime().getTime()-(p2.getTime().getTime
()% 86400000L);
La sottrazione la fai solo se hai date che non cominciano a
mezzanotte.
Nel tuo caso bastava:
         long millisecgiorno1=p1.getTime().getTime();
Il resto è OK.


Vedo che la tua "formula" per il calcolo della differenza giorni concorda
con la mia, ma da una mia prova ho notato che stranamente il resto della
divisione
long giorni = (d2.getTime()-d1.getTime())/(24*60*60*1000);
non dà sempre 0 come mi aspetterei usando delle Date con orario 00:00:00
Hai per caso provato i 3 casi che ho indicato nel post principale??


 non dà sempre 0 come mi aspetterei usando delle Date con
orario 00:00:00
Guarda che ti sbagli, la tua era:
long giorni = (d2.getTime()-d1.getTime())%(24*60*60*1000);
CarloP

 
Mi sa che il problema dipende dall'ora legale che potrebbe essere in 
vigore solo in una delle due date.
Una volta avevo bisogno di calcolare la differenza fra due date ed era 
venuto fuori questo problema.
Ne era venuto fuori anche un'altro che ora non ricordo bene. Se non 
sbaglio era che in qualche momento intorno agli anni 70 un'ora sembra 
sia stata saltata. Boh, spero di non aver detto una stupidaggine.
Avevo risolto utilizzando una classe per il calcolo delle differenze fra 
date che mi era stata indicata su questo newsgroup. Se la trovo posto il 
codice.
Andrea


Hai ragione mi ero spiegato male, il modulo lo facevo come riprova e mi
soprendeva che non fosse 0

 
Faresti un favore anche a me. Grazie.

 [stracut]
Davvero complimenti per la tua "didattica" esposizione!

 ha scritto nel messaggio
news:MPG.199b30416...@news.fu-berlin.de...


 codice.
Ecco il link al messaggio:
http://groups.google.it/groups?hl=it&lr=&ie=UTF-8&oe=UTF-8&selm=b7j5kq%24p7b%241%40fata.cs.interbusiness.it
Andrea

 Cambia leggermente la specifica: se e' lo stesso giorno torna zero.
Ovviamente ha il difetto di fare un loop molto lungo se le due date sono 
di anni molto distanti tra di loro!
La mia proposta originaria (sempre valida!) era in un vecchio link:
http://groups.google.it/groups?hl=it&lr=&ie=UTF-8&oe=UTF-8&selm=b7j5kq%24p7b%241%40fata.cs.interbusiness.it
- Dario

 Dopo alcune prove direi che funziona, cmq chi avesse idee migliori:
Un po + elegante e compatta della tua...
ma sostanzialmente lo stesso algoritmo:
import java.util.Calendar;
class A48 {
   // Return # of days between two Calendar.
   // Return 0 for the same day
   //        1 for today/tomorrow, ...
   //       -1 for tomorrow/today, ...
   public static int getNumDaysFromTo(Calendar cFrom, Calendar cTo) {
     Calendar c1 = (Calendar)cFrom.clone();
     Calendar c2 = (Calendar)cTo.clone();
     boolean  swap = c1.getTime().getTime() > c2.getTime().getTime();
     if(swap) {
       Calendar c = c1;
       c1 = c2;
       c2 = c;
     }
     if(c1.get(Calendar.YEAR) == c2.get(Calendar.YEAR) &&
        c1.get(Calendar.DAY_OF_YEAR ) == c2.get(Calendar.DAY_OF_YEAR))
       return 0;
     int g = 0;
     while(c1.getTime().getTime() < c2.getTime().getTime()) {
       g++;
       c1.add(Calendar.DAY_OF_YEAR, 1);
     }
     return swap ? -g : g;
   }
   public static void main(String args[]) {
     Calendar c1 = Calendar.getInstance();
     Calendar c2 = Calendar.getInstance();
     c2.set(Calendar.DAY_OF_MONTH, 31);
     System.out.println("c1: " + c1.getTime());
     System.out.println("c2: " + c2.getTime());
     System.out.println("# days: " + getNumDaysFromTo(c1, c2));
   }
}
E' + generica: le due date possono anche essere invertite.
Non usa la funzione di utilita' conv da te creata.
Cambia leggermente la specifica: se e' lo stesso giorno torna zero.
Ma sostanzialmente e' la tua!
- Dario

 Ma sostanzialmente e' la tua!
Giusto per la precisione. Quella di cui ho riportato il link non e' mia. 
Io l'ho solo utilizzata
Andrea
P.S.
Speriamo non venga fuori che SCO usa lo stesso algoritmo all'interno di 
un suo programma, altrimenti mi fa causa! ;-)