2010-08-19 23 views
39

Il mio cuore sta sanguinando internamente dopo dover andare così in profondità sottrarre due date per calcolare la durata in numero di giorni:Come sottrai le date in Java?

GregorianCalendar c1 = new GregorianCalendar(); 
    GregorianCalendar c2 = new GregorianCalendar(); 
    c1.set(2000, 1, 1); 
    c2.set(2010,1, 1); 
    long span = c2.getTimeInMillis() - c1.getTimeInMillis(); 
    GregorianCalendar c3 = new GregorianCalendar(); 
    c3.setTimeInMillis(span); 
    long numberOfMSInADay = 1000*60*60*24; 
    System.out.println(c3.getTimeInMillis()/numberOfMSInADay); //3653 

dove è solo 2 righe di codice in .NET, o qualsiasi lingua moderna si nome .

Questo è atroce di java? O c'è un metodo nascosto che dovrei sapere?

Invece di utilizzare GregorianCalendar, è corretto utilizzare la classe Date in util? Se è così, dovrei stare attento a cose sottili come l'anno 1970?

Grazie

+1

perchè si usa c3? Afaik potresti lasciare fuori almeno le due linee per c3;) – ZeissS

risposta

49

E 'infatti uno dei più grandi fallimenti epici nella API standard di Java. Avere un po 'di pazienza, quindi otterrete la vostra soluzione nel gusto della nuova API Date and Time specificata da JSR 310/ThreeTen che è (molto probabilmente) sarà inclusa nell'imminente Java 8.

Fino ad allora, è possibile scappare con JodaTime.

DateTime dt1 = new DateTime(2000, 1, 1, 0, 0, 0, 0); 
DateTime dt2 = new DateTime(2010, 1, 1, 0, 0, 0, 0); 
int days = Days.daysBetween(dt1, dt2).getDays(); 

Il suo creatore, Stephen Colebourne, è tra l'altro il ragazzo dietro JSR 310, in modo che sarà un aspetto molto simile.

+3

Ho un piccolo progetto e ne ho bisogno solo in pochi posti. Tornando da .NET, sono solo un po 'infuriato e frustrato da java. Grazie per la conferma, però. – Haoest

+1

È anche possibile creare un metodo di utilità e nasconderlo lontano nelle profondità del codice in modo da non essere direttamente infastidito dalla brutta API di Calendar;) – BalusC

+0

JSR 310 ha mai visto il giorno? –

3

Se si hanno a che fare con le date, è una buona idea dare un'occhiata alla libreria del tempo di joda per un modello di manipolazione delle date più sano.

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

3

Ebbene si può rimuovere la terza istanza di calendario.

GregorianCalendar c1 = new GregorianCalendar(); 
GregorianCalendar c2 = new GregorianCalendar(); 
c1.set(2000, 1, 1); 
c2.set(2010,1, 1); 
c2.add(GregorianCalendar.MILLISECOND, -1 * c1.getTimeInMillis()); 
+3

Non penso che GregorianCalendar sia immutabile, quindi se dovessi usare nuovamente c2 più tardi, mi piacerebbe averlo come valore inizialmente definito. – Haoest

18

È possibile utilizzare il seguente approccio:

SimpleDateFormat formater=new SimpleDateFormat("yyyy-MM-dd"); 

long d1=formater.parse("2001-1-1").getTime(); 
long d2=formater.parse("2001-1-2").getTime(); 

System.out.println(Math.abs((d1-d2)/(1000*60*60*24))); 
0

Ecco l'approccio di base,

DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); 

Date beginDate = dateFormat.parse("2013-11-29"); 
Date endDate = dateFormat.parse("2013-12-4"); 

Calendar beginCalendar = Calendar.getInstance(); 
beginCalendar.setTime(beginDate); 

Calendar endCalendar = Calendar.getInstance(); 
endCalendar.setTime(endDate); 

Non c'è modo semplice per la sua attuazione. Possiamo usare il metodo Calendar.add con il ciclo. I giorni meno tra BeginDate e endDate e il codice implementato come di seguito,

int minusDays = 0; 
while (true) { 
    minusDays++; 

    // Day increasing by 1 
    beginCalendar.add(Calendar.DAY_OF_MONTH, 1); 

    if (dateFormat.format(beginCalendar.getTime()). 
      equals(dateFormat.format(endCalendar).getTime())) { 
    break; 
    } 
} 
System.out.println("The subtraction between two days is " + (minusDays + 1));** 
+0

Ottimo uso della parola "sottrazione" :) –