PDA

View Full Version : [JAVA] CALCOLO DISTANZE TRA 2 DATE


robby87
29-05-2006, 22:24
Qualkuno mi riesce a postare un algoritmo per il calcolo della distanza tra 2 date?? io ho fatto l'input in vari text field ed ho i valori in 2 variabili per data: giorno1 mese1 anno1 (riguardo la prima data) e giorno2 mese2 anno2(riguardo la seconda data)! Come faccio a calcolare la distanza tra le 2?? le variabili sono tutte di tipo int...


GRAZIE A TUTTI!!! :muro: :help:

sottovento
30-05-2006, 01:54
Qualkuno mi riesce a postare un algoritmo per il calcolo della distanza tra 2 date?? io ho fatto l'input in vari text field ed ho i valori in 2 variabili per data: giorno1 mese1 anno1 (riguardo la prima data) e giorno2 mese2 anno2(riguardo la seconda data)! Come faccio a calcolare la distanza tra le 2?? le variabili sono tutte di tipo int...


GRAZIE A TUTTI!!! :muro: :help:

Ciao,
in Java esistono almeno due tecniche per effettuare questo calcolo.

1 - (lo preferisco). Crei due variabili di tipo Calendar, mediante il metodo set() imposti giorno/mese/anno (volendo anche ore minuti secondi e millisecondi), dopo di che ti chiami la Calendar.getTimeInMillis(). Per ottenere la distanza fra due date, ti basta fare la sottrazione.
Se poi vuoi trasformare nuovamente tutto in giorni/mesi/anni, ti bastera' creare una nuova variabile Calendar, fare la setTimeInMillis() e poi, mediante il metodo get(), leggere giorno/mese/anno.
Sembra laboriosa ma e' tutto codice di "routine". E' la soluzione che preferisco perche' e' simile a quanto si puo' fare in linguaggio C. Quindi si puo' applicare la stessa soluzione ad ambiti diversi;

2 - (leggermente piu' veloce) puoi usare la Calendar.add() che ti permette di aggiungere/sottrarre giorni/mesi/anni

Spero ti sia utile

High Flying
Sottovento

robby87
30-05-2006, 16:31
Calendar data1,data2;
double dat1,dat2,dist;
data1.set(aa1,mm1,gg1);
data2.set(aa2,mm2,gg2);

dat1= data1.getTimeInMillis();
dat2= data1.getTimeInMillis();

dist=dat1-dat2;

Può andare così?? nn ho capito bene la fine se vuoi mettermi tu qualke riga??? grazie mille...

cmq aa1,mm1,gg1 sono variabili di tipo intero ke insieme formano la data!

sottovento
31-05-2006, 16:00
Calendar data1,data2;
double dat1,dat2,dist;
data1.set(aa1,mm1,gg1);
data2.set(aa2,mm2,gg2);

dat1= data1.getTimeInMillis();
dat2= data1.getTimeInMillis();

dist=dat1-dat2;

Può andare così?? nn ho capito bene la fine se vuoi mettermi tu qualke riga??? grazie mille...

cmq aa1,mm1,gg1 sono variabili di tipo intero ke insieme formano la data!

Ciao e scusa la risposta in ritardo.
Se hai le date, puoi fare una cosa del genere:


Calendar firstDate = Calendar.getInstance ();
firstDate.set (Calendar.YEAR, year);
firstDate.set (Calendar.MONTH, month - 1); // Month starts from 0
firstDate.set (Calendar.DAY_OF_MONTH, day);
firstDate.set (Calendar.HOUR_OF_DAY, hour);
firstDate.set (Calendar.MINUTE, minute);
firstDate.set (Calendar.SECOND, second);
firstDate.set (Calendar.MILLISECOND, millisecond);

// You can do the same for the second date, and then

long distance = firstDate.getTimeInMillis() - secondDate.getTimeInMillis();



Questo codice ti ritorna la distanza fra le due date, espresse in millisecondi.
Se vuoi tornare indietro:


Calendar cal = Calendar.getInstance ();
cal.setTimeInMillis (distance);

int dist_year = cal.get (Calendar.YEAR);
int dist_month = cal.get (Calendar.MONTH) + 1;
int day = cal.get (Calendar.DAY_OF_MONTH);



Spero ti sia utile

High Flying
Sottovento

theClimber
31-05-2006, 19:44
Nell'ottica di una soluzione "alternativa" e del non re-inventare la ruota, si puo' sempre ricorrere a librerie consolidate. Relativamente a date e intervalli di tempo:

http://joda-time.sourceforge.net/

Relativamente ad intervalli e durate trovi degli esempi:

http://joda-time.sourceforge.net/key_interval.html

Ciao

robby87
31-05-2006, 20:07
mi sballa!! cioè nn calcola la differenza giusta...mi da sempre lo stesso risultato!!!
per esempio in questa istruzione

firstDate.set (Calendar.YEAR, year);
la variabile year( la seconda ovviamente) è di tipo intero vero???

sottovento
01-06-2006, 01:53
mi sballa!! cioè nn calcola la differenza giusta...mi da sempre lo stesso risultato!!!
per esempio in questa istruzione

firstDate.set (Calendar.YEAR, year);
la variabile year( la seconda ovviamente) è di tipo intero vero???
Si, e' di tipo intero. Questo metodo l'ho usato parecchie volte, senza problemi.
Se sballa, probabilmente il problema e' in qualcosa di correlato:
- leggi le date correttamente?
- leggi anche ore/minuti/secondi?
- Inizializzi tutto correttamente?
- La Calendar.getInstance() dovrebbe riportarti un Gregorian calendar e non dovresti aver problemi.

Pubblica il codice interessato, o spediscimelo in pvt.
Si tratta di poche righe di software (spero).
Per questo problema, nonostante l'ottimo suggerimento di theClimber, non mi sembra il caso di ricorrere a librerie esterne.
La Calendar mi sembra sufficiente.
Casomai provero' l'uso di quella libreria per quanto riguarda il calcolo del compleanno di mia moglie, visto che segue il calendario buddista e tutti gli anni non capisco quando festeggia :).
Se hai tempo di aspettare a causa del fuso orario, posso aiutarti

High Flying
Sottovento

robby87
01-06-2006, 11:28
Questo è il mio programma:

import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
import java.lang.*;
import java.util.*;




class GestoreFinestra implements WindowListener
{
public void windowIconified(WindowEvent e) {}
public void windowDeiconified(WindowEvent e) {}
public void windowActivated(WindowEvent e) {}
public void windowDeactivated(WindowEvent e) {}
public void windowOpened(WindowEvent e) {}
public void windowClosed(WindowEvent e) {}

public void windowClosing(WindowEvent e)
{
System.out.println("Programma terminato...");
System.exit(0);
}
}
public class ConvertFrame extends JFrame implements ActionListener
{
public JPanel p = new JPanel();
public JPanel p2 = new JPanel();
public JPanel p3 = new JPanel();
public JPanel p1 = new JPanel();

public JTextField mese1 = new JTextField(15);
public JTextField giorno1 = new JTextField(15);
public JTextField anno1 = new JTextField(15);

public JTextField mese2 = new JTextField(15);
public JTextField giorno2 = new JTextField(15);
public JTextField anno2 = new JTextField(15);

public JButton confronta = new JButton("Confronto date");
public JButton festa = new JButton("Controllo festività");
public JButton exit = new JButton("Uscita");
public JButton giorno = new JButton("Stabilisci giorno");
public String prima,sec;
public int i,contr=0;


//variabili per metodo diff
/* Calendar data1 = Calendar.getInstance ();
Calendar data2 = Calendar.getInstance ();
Calendar dat_dist = Calendar.getInstance ();
*/
int dist_aa,dist_mm,dist_gg;
long dist;


public ConvertFrame()
{
super("...Bondavalli Roberto... GESTIONE CLASSE DATA");

addWindowListener(new GestoreFinestra());

p2.setLayout(new GridLayout(4,2,0,0));
p2.add(new JLabel("Giorno: "));
p2.add(giorno1);

p2.add(new JLabel("Mese: "));
p2.add(mese1);

p2.add(new JLabel("Anno: "));
p2.add(anno1);


p3.setLayout(new GridLayout(4,2,0,0));

p3.add(new JLabel("Giorno: "));
p3.add(giorno2);

p3.add(new JLabel("Mese: "));
p3.add(mese2);

p3.add(new JLabel("Anno: "));
p3.add(anno2);


p1.setLayout(new GridLayout(2,2,0,0));
p1.add(confronta);
p1.add(festa);
p1.add(giorno);
p1.add(exit);



p.setLayout(new GridLayout(5,1));
p.add(new JLabel("1° DATA: "));
p.add(p2);
p.add(new JLabel("2° DATA: "));
p.add(p3);
p.add(p1);

add(p);


setSize(200,200 );
confronta.addActionListener(this);
festa.addActionListener(this);
exit.addActionListener(this);
giorno.addActionListener(this);

}

public void actionPerformed(ActionEvent e)
{
int ok1=0,ok2=0;;
String bottone = e.getActionCommand();
date d= new date ();

if (e.getActionCommand()== "Uscita")
{
System.exit(0);
}
else
if (e.getActionCommand()== "Confronto date")
{

ok1=d.Ctrl1();
ok2=d.Ctrl2();

if(ok1==1 && ok2==1)
{
d.Tras();
d.diff();
// JOptionPane.showMessageDialog( null,"Distanza "+dist_aa"ciao");


}else
JOptionPane.showMessageDialog( null,"Inserimento data errato ");

}


}


public static void main(String args[])
{

ConvertFrame f = new ConvertFrame();
f.pack();
f.setVisible(true);



}

class date
{
int dim;
String giorno,mese,anno;
int gg1,mm1,aa1;//variabili prima data
int gg2,mm2,aa2;

public void Tras()
{



try
{
giorno = giorno1.getText();
gg1=Integer.valueOf(giorno).intValue();
System.out.println("gg1: "+gg1);
mese = mese1.getText();
mm1=Integer.valueOf(mese).intValue();
System.out.println("mm1: "+mm1);

anno = anno1.getText();
aa1=Integer.valueOf(anno).intValue();
System.out.println("aa1: "+aa1);

giorno = giorno2.getText();
gg2=Integer.valueOf(giorno).intValue();
System.out.println("gg2: "+gg2);

mese = mese2.getText();
mm2=Integer.valueOf(mese).intValue();
System.out.println("mm1: "+mm2);

anno = anno2.getText();
aa2=Integer.valueOf(anno).intValue();
System.out.println("aa1: "+aa2);
}
catch (Exception e)
{
System.out.println("Numero NON corretto");
JOptionPane.showMessageDialog( null,"Inserimento data errato ");
return;
}


if( gg1==gg2 && mm1==mm2 && aa1==aa2 )
{
JOptionPane.showMessageDialog( null,"Inserimento data errato (DATE UGUALI) ");
}


}



public int Ctrl1()
{
if(aa1 >3000 && aa1< -1000)
{
JOptionPane.showMessageDialog( null,"Inserimento data errato ");
}
if(mm1 >12)
{
JOptionPane.showMessageDialog( null,"Inserimento data errato ");
}

if(mm1==2 && gg1 >28)
{
JOptionPane.showMessageDialog( null,"Inserimento data errato ");
}

if( (mm1==11 || mm1==4 || mm1==6 || mm1==9) && gg1 >30)
{
JOptionPane.showMessageDialog( null,"Inserimento data errato ");
}else
if(gg1>31)
{
JOptionPane.showMessageDialog( null,"Inserimento data errato ");
}

return 1;
}



public int Ctrl2()
{

if(aa2 >3000 && aa2< -1000)
{
JOptionPane.showMessageDialog( null,"Inserimento data errato ");
}

if(mm2 >12)
{
JOptionPane.showMessageDialog( null,"Inserimento data errato ");
}

if(mm2==2 && gg2 >28)
{
JOptionPane.showMessageDialog( null,"Inserimento data errato ");
}

if( (mm2==11 || mm2==4 || mm2==6 || mm2==9) && gg2 >30)
{
JOptionPane.showMessageDialog( null,"Inserimento data errato ");
}else

if(gg2>31)
{
JOptionPane.showMessageDialog( null,"Inserimento data errato ");
}
return 1;

}

public void diff()
{
Calendar data1= Calendar.getInstance ();
Calendar data2 = Calendar.getInstance ();
Calendar dat_dist = Calendar.getInstance ();




data1.set(Calendar.YEAR,aa1);

data1.set(Calendar.MONTH,mm1);

data1.set(Calendar.DAY_OF_MONTH,gg1);

data1.set (Calendar.MINUTE,0);

data1.set (Calendar.SECOND, 0);

data1.set (Calendar.MILLISECOND, 0);





data2.set(Calendar.YEAR,aa2);

data2.set(Calendar.MONTH,mm2);

data2.set(Calendar.DAY_OF_MONTH,gg2);

data2.set (Calendar.MINUTE,0);

data2.set (Calendar.SECOND, 0);

data2.set (Calendar.MILLISECOND, 0);


dist = data1.getTimeInMillis () - data2.getTimeInMillis();

dat_dist.setTimeInMillis (dist);


dist_aa= dat_dist.get (Calendar.YEAR);
dist_mm = dat_dist.get (Calendar.MONTH);
dist_gg = dat_dist.get (Calendar.DAY_OF_MONTH);

System.out.println("dist_aa: "+dist_aa);
System.out.println("dist_mm: "+dist_mm);
System.out.println("dist_gg: "+dist_gg);


}



}

}


mi stampa sempre la stessa data come output della distanza... V PREGO !! AIUTO!!! :help: :help: :help:

trallallero
01-06-2006, 14:10
Ciao.

Il tuo prog e' piu' o meno giusto (ocio che i mesi partono da 0)

L'errore e' nella logica:

l'istruzione
dat_dist.setTimeInMillis (dist);
e' errata.

"dist" e' un intervallo di tempo non una data.

ex: tra 01/01/2000 e 02/01/2000 c'e un giorno di differenza.
eseguendo: dat_dist.setTimeInMillis (dist) tu imposti la data 01/01/1970 (quella base) + un giorno.

Per sapere la differenza devi usare un altro metodo, io non sono esperto di java ma userei
anno1 - anno2
mese1 - mese2
etc

Spero di essermi capito bene :-)

sottovento
01-06-2006, 15:19
Ciao.

Il tuo prog e' piu' o meno giusto (ocio che i mesi partono da 0)

L'errore e' nella logica:

l'istruzione
dat_dist.setTimeInMillis (dist);
e' errata.

"dist" e' un intervallo di tempo non una data.

ex: tra 01/01/2000 e 02/01/2000 c'e un giorno di differenza.
eseguendo: dat_dist.setTimeInMillis (dist) tu imposti la data 01/01/1970 (quella base) + un giorno.

Per sapere la differenza devi usare un altro metodo, io non sono esperto di java ma userei
anno1 - anno2
mese1 - mese2
etc

Spero di essermi capito bene :-)

Hai ragione, e chiedo scusa a robby87 per il suggerimento mezzo errato.
La soluzione e' http://forum.java.sun.com/thread.jspa?threadID=164882&messageID=631261 (fa tutto come suggerito fino ai millisecondi), dopo di che si approssima il calcolo dei giorni/mesi/anni.

Riporto l'ultimo messaggio (compreso di firma, ovviamente):


Hi,

The final answer how to calculate the difference between two dates:

// First convert the from and to Calender to long (milli seconds)
// MAKE SURE THE Hour, Seconds and Milli seconds are set to 0, if you
// already have you own Claender object otherwise the time will be
// used in the comparision, later on.
long from = new java.util.GregorianCalendar(2003, 1, 20).getTime().getTime();
long to = new java.util.GregorianCalendar(2003, 2, 5).getTime().getTime();


// Next subtract the from date from the to date (make sure the
// result is a double, this is needed in case of Winter and Summer
// Time (changing the clock one hour ahead or back) the result will
// then be not exactly rounded on days. If you use long, this slighty
// different result will be lost.
double difference = to - from;


// Next divide the difference by the number of milliseconds in a day
// (1000 * 60 * 60 * 24). Next round the result, this is needed of the
// Summer and Winter time. If the period is 5 days and the change from
// Winter to Summer time is in the period the result will be
// 5.041666666666667 instead of 5 because of the extra hour. The
// same will happen from Winter to Summer time, the result will be
// 4.958333333333333 instead of 5 because of the missing hour. The
// round method will round both to 5 and everything is OKE....
long days = Math.round((difference/(1000*60*60*24)));


// Now we can print the day difference... Try it, it also works with
// Feb 29...
System.out.println(days);

Have fun,
Gras_22

robby87
01-06-2006, 18:03
io nn c capisco + niente...mi potete mettere a posto il codice nel programma e postarmi tutto il programma??? v prego, vi chiedo solo questo aiuto...

sottovento
02-06-2006, 15:45
io nn c capisco + niente...mi potete mettere a posto il codice nel programma e postarmi tutto il programma??? v prego, vi chiedo solo questo aiuto...
Purtroppo non ho il tempo di fare questa operazione. Pero' ti posso risolvere il problema piu' importante:


import java.util.*;

class DiffDate
{
private int years;
private int months;
private int days;

public DiffDate ()
{
years = 0;
months = 0;
days = 0;
}

public DiffDate (int years, int months, int days)
{
this.years = years;
this.months = months;
this.days = days;
}

public void setYears (int years)
{
this.years = years;
}

public void setMonths (int month)
{
this.months = months;
}

public void setDays (int days)
{
this.days = days;
}

public int getYears () { return years; }
public int getMonths () { return months; }
public int getDays () { return days; }
}

public class Differences
{
public static int numDays (Calendar cal)
{
return cal.getActualMaximum (Calendar.DAY_OF_MONTH);
}

public static int numDaysPreviousMonth (Calendar cal)
{
Calendar c = (Calendar)cal.clone ();
c.roll (Calendar.MONTH, -1);
return c.getActualMaximum (Calendar.DAY_OF_MONTH);
}

public static DiffDate diffDates (Calendar beforeDate, Calendar afterDate)
{
int carryDay = 0;
int carryMonth = 0;
int diffday = afterDate.get(Calendar.DAY_OF_MONTH) - beforeDate.get(Calendar.DAY_OF_MONTH);
if (diffday < 0)
{
diffday += numDaysPreviousMonth (afterDate);
carryDay = 1;
}

int diffmonth = afterDate.get(Calendar.MONTH) - beforeDate.get(Calendar.MONTH) - carryDay;
if (diffmonth < 0)
{
diffmonth += 12;
carryMonth = 1;
}
int diffyear = afterDate.get(Calendar.YEAR) - beforeDate.get(Calendar.YEAR) - carryMonth;
return new DiffDate (diffyear, diffmonth, diffday);
}

public static void main (String[] args)
{
Calendar degree1 = Calendar.getInstance ();
degree1.set (Calendar.YEAR, 1992);
degree1.set (Calendar.MONTH, 9);
degree1.set (Calendar.DAY_OF_MONTH, 28);

Calendar degree2 = Calendar.getInstance ();
degree2.set (Calendar.YEAR, 2000);
degree2.set (Calendar.MONTH, 6);
degree2.set (Calendar.DAY_OF_MONTH, 6);
Calendar rightNow = Calendar.getInstance ();

Calendar wedding = Calendar.getInstance ();
wedding.set (Calendar.YEAR, 2004);
wedding.set (Calendar.MONTH, 5);
wedding.set (Calendar.DAY_OF_MONTH, 4);

DiffDate dd1 = diffDates (degree1, rightNow);
DiffDate dd2 = diffDates (degree2, rightNow);
DiffDate dd3 = diffDates (wedding, rightNow);

System.out.println ("Caro Sottovento, stai invecchiando. Dalla tua prima laurea sono passati");
System.out.println ("" + dd1.getYears() + " anni");
System.out.println ("" + dd1.getMonths() + " mesi");
System.out.println ("" + dd1.getDays() + " giorni");
System.out.println ("Dalla tua seconda laurea sono passati");
System.out.println ("" + dd2.getYears() + " anni");
System.out.println ("" + dd2.getMonths() + " mesi");
System.out.println ("" + dd2.getDays() + " giorni");
System.out.println ("Dal tuo matrimonio sono passati");
System.out.println ("" + dd3.getYears() + " anni");
System.out.println ("" + dd3.getMonths() + " mesi");
System.out.println ("" + dd3.getDays() + " giorni");
System.out.println ("Non e' l'ora di mettere la testa a posto?");
}
}


Stampera'


Caro Sottovento, stai invecchiando. Dalla tua prima laurea sono passati
13 anni
7 mesi
5 giorni
Dalla tua seconda laurea sono passati
5 anni
10 mesi
27 giorni
Dal tuo matrimonio sono passati
1 anni
11 mesi
29 giorni
Non e' l'ora di mettere la testa a posto?


High Flying
Sottovento

robby87
03-06-2006, 10:58
Non c'ho capito niente...io purtroppo non sopporto java

sottovento
03-06-2006, 12:19
Non c'ho capito niente...io purtroppo non sopporto java

1 - copia la class DiffDate nel file DiffDate.java

2 - copia il metodo
public static int numDaysPreviousMonth (Calendar cal)
in una classe di tuo gradimento (magari una dedicata a solo questo lavoro);

3 - copia il metodo
public static DiffDate diffDates (Calendar beforeDate, Calendar afterDate)
nella classe definita al punto 2.
Questo e' il metodo che chiamerai per avere la differenza fra le due date, espressa in giorni, mesi ed anni. Fai attenzione che non ho fatto i controlli necessari, per cui beforeDate deve essere antecedente ad afterDate.

4 - usa questo metodo nel tuo programma.

Tutto qui.

High Flying
Sottovento

robby87
03-06-2006, 12:37
evvai c sono riuscito!!! come faccio a stampare due valori con un:
JOptionPane.showMessageDialog??? cioè un valore c sono riuscito facendo così:
JOptionPane.showMessageDialog( null,"La distanza tra le due date è di giorni:"+dist_gg);

ma come faccio a stampare il valore di due variabili in un unica finestra?? GRAZIE DI TUTTO SIETE FANTASTICI!

sottovento
04-06-2006, 15:03
evvai c sono riuscito!!! come faccio a stampare due valori con un:
JOptionPane.showMessageDialog??? cioè un valore c sono riuscito facendo così:
JOptionPane.showMessageDialog( null,"La distanza tra le due date è di giorni:"+dist_gg);

ma come faccio a stampare il valore di due variabili in un unica finestra?? GRAZIE DI TUTTO SIETE FANTASTICI!

Spero di aver capito bene, in caso contrario perdonami.
Devi semplicemente ripetere la stessa cosa:

JOptionPane.showMessageDialog (null, "La distanza e' di " + dist_gg + " giorni, di " + dist_mm + " mesi, " + dist_yy + " anni");

High Flying
Sottovento

robby87
04-06-2006, 20:55
grazie...ho fatto tutto!!! grazie sottovento! sei mitico!! scusa se t ho fatto perdere tempo!!