Unterschied in Tagen zwischen zwei Daten in Java?

81

Ich muss die Anzahl der Tage zwischen zwei Daten ermitteln : einer stammt aus einem Bericht und einer ist das aktuelle Datum. Mein Ausschnitt:

  int age=calculateDifference(agingDate, today);

Hier calculateDifferenceist eine private Methode agingDateund todaysind DateObjekte, nur zur Verdeutlichung. Ich habe zwei Artikel aus einem Java-Forum verfolgt, Thread 1 / Thread 2 .

Es funktioniert gut in einem eigenständigen Programm, obwohl ich einen ungewöhnlichen Wertunterschied erhalte, wenn ich dies in meine Logik einbeziehe, um aus dem Bericht zu lesen.

Warum passiert es und wie kann ich es beheben?

EDIT:

Ich erhalte eine größere Anzahl von Tagen als die tatsächliche Anzahl von Tagen.

public static int calculateDifference(Date a, Date b)
{
    int tempDifference = 0;
    int difference = 0;
    Calendar earlier = Calendar.getInstance();
    Calendar later = Calendar.getInstance();

    if (a.compareTo(b) < 0)
    {
        earlier.setTime(a);
        later.setTime(b);
    }
    else
    {
        earlier.setTime(b);
        later.setTime(a);
    }

    while (earlier.get(Calendar.YEAR) != later.get(Calendar.YEAR))
    {
        tempDifference = 365 * (later.get(Calendar.YEAR) - earlier.get(Calendar.YEAR));
        difference += tempDifference;

        earlier.add(Calendar.DAY_OF_YEAR, tempDifference);
    }

    if (earlier.get(Calendar.DAY_OF_YEAR) != later.get(Calendar.DAY_OF_YEAR))
    {
        tempDifference = later.get(Calendar.DAY_OF_YEAR) - earlier.get(Calendar.DAY_OF_YEAR);
        difference += tempDifference;

        earlier.add(Calendar.DAY_OF_YEAR, tempDifference);
    }

    return difference;
}

Hinweis :

Leider hat mir keine der Antworten geholfen, das Problem zu lösen. Ich habe dieses Problem mit Hilfe der Joda-Zeitbibliothek gelöst .

Venkat
quelle
3
Was meinen Sie mit ungewöhnlichen Differenzwerten? Könnten Sie bitte expliziter sein oder ein Beispiel geben?
Marcel Gheorghita
1
Können Sie den Code für die berechneDifferenzmethode veröffentlichen?
Eugene
Zu Ihrer Information, die störenden alten Datum Zeitklassen wie java.util.Date, java.util.Calendarund java.text.SimpleDateFormatsind jetzt Erbe , durch die verdrängte java.time Klassen. Siehe Tutorial von Oracle . Ebenso befindet sich das Joda-Time- Projekt jetzt im Wartungsmodus , wobei das Team die Migration zu den Klassen java.time empfiehlt.
Basil Bourque

Antworten:

149

Ich würde vorschlagen, dass Sie die ausgezeichnete Joda Time- Bibliothek anstelle des fehlerhaften java.util.Date und Ihrer Freunde verwenden. Du könntest einfach schreiben

import java.util.Date;
import org.joda.time.DateTime;
import org.joda.time.Days;

Date past = new Date(110, 5, 20); // June 20th, 2010
Date today = new Date(110, 6, 24); // July 24th 
int days = Days.daysBetween(new DateTime(past), new DateTime(today)).getDays(); // => 34
Adam Schmideg
quelle
3
joda-time.sourceforge.net/faq.html#datediff - Ich wollte das Gleiche vorschlagen.
Nebril
2
jodaInstance = new DateTime (jdkDate); Informationen zur Konvertierung zwischen joda time und java.util.Date und Freunden finden Sie unter joda-time.sourceforge.net/userguide.html#JDK_Interoperability
Adam Schmideg
2
@ven coder - Ich denke, Sie können es als separate Frage zur Verwendung von joda time posten. Sie können auch ein Code-Snippet bereitstellen, das das scheinbar falsche Ergebnis liefert.
Adam Schmideg
2
@ven coder - Ich habe den Beispielcode aktualisiert, er funktioniert für mich. Ich sehe diese Frage beantwortet. Zeigen Sie den Code, der für Sie nicht funktioniert, entweder hier oder in einer separaten Frage.
Adam Schmideg
1
Zu Ihrer Information , das Joda-Time- Projekt befindet sich jetzt im Wartungsmodus. Das Team empfiehlt die Migration zu den Klassen java.time . Siehe Tutorial von Oracle .
Basil Bourque
48

Ich könnte zu spät sein, um am Spiel teilzunehmen, aber was zum Teufel? :) :)

Denken Sie, dass dies ein Threading-Problem ist? Wie verwenden Sie zum Beispiel die Ausgabe dieser Methode? ODER

Können wir Ihren Code ändern, um etwas so Einfaches zu tun wie:

Calendar calendar1 = Calendar.getInstance();
    Calendar calendar2 = Calendar.getInstance();
    calendar1.set(<your earlier date>);
    calendar2.set(<your current date>);
    long milliseconds1 = calendar1.getTimeInMillis();
    long milliseconds2 = calendar2.getTimeInMillis();
    long diff = milliseconds2 - milliseconds1;
    long diffSeconds = diff / 1000;
    long diffMinutes = diff / (60 * 1000);
    long diffHours = diff / (60 * 60 * 1000);
    long diffDays = diff / (24 * 60 * 60 * 1000);
    System.out.println("\nThe Date Different Example");
    System.out.println("Time in milliseconds: " + diff
 + " milliseconds.");
    System.out.println("Time in seconds: " + diffSeconds
 + " seconds.");
    System.out.println("Time in minutes: " + diffMinutes 
+ " minutes.");
    System.out.println("Time in hours: " + diffHours 
+ " hours.");
    System.out.println("Time in days: " + diffDays 
+ " days.");
  }
Suji
quelle
18
Dieser Code berücksichtigt nicht die Sommerzeit, daher ist das Ergebnis der Differenz in Tagen möglicherweise nicht korrekt.
Johanna
@Johanna Obwohl es ziemlich spät ist, kannst du bitte ein Beispiel geben, wenn dies fehlschlägt. Ich habe viel versucht, konnte aber keine Datumsbereiche finden, für die dies fehlschlägt. Danke dir.
Abhilash
4
Dieser Fehler tritt nur auf, wenn Sie sich in einer Zeitzone (Ihrer lokalen Zeitzoneneinstellung) befinden, in der die Sommerzeit verwendet wird, z. B. Mitteleuropäische Zeit, Berlin, Paris oder Amsterdam. Der Start- und Endtag der Sommerzeit hat keine 24 Stunden, zum Beispiel hatte der 30. März 2014 nur 23 Stunden, während der 26. Oktober 2014 25 Stunden hat. Wenn das frühere Datum vor dem 30. März 2:00 Uhr und das spätere Datum nach dem 30. März 3:00 Uhr liegt, schlägt die Berechnung fehl.
Johanna
23

Das diff / (24 * usw.) berücksichtigt die Zeitzone nicht. Wenn Ihre Standardzeitzone eine Sommerzeit enthält, kann dies die Berechnung beeinträchtigen.

Dieser Link hat eine nette kleine Implementierung.

Hier ist die Quelle des obigen Links für den Fall, dass der Link ausfällt:

/** Using Calendar - THE CORRECT WAY**/  
public static long daysBetween(Calendar startDate, Calendar endDate) {  
  //assert: startDate must be before endDate  
  Calendar date = (Calendar) startDate.clone();  
  long daysBetween = 0;  
  while (date.before(endDate)) {  
    date.add(Calendar.DAY_OF_MONTH, 1);  
    daysBetween++;  
  }  
  return daysBetween;  
}  

und

/** Using Calendar - THE CORRECT (& Faster) WAY**/  
public static long daysBetween(final Calendar startDate, final Calendar endDate)
{
  //assert: startDate must be before endDate  
  int MILLIS_IN_DAY = 1000 * 60 * 60 * 24;  
  long endInstant = endDate.getTimeInMillis();  
  int presumedDays = 
    (int) ((endInstant - startDate.getTimeInMillis()) / MILLIS_IN_DAY);  
  Calendar cursor = (Calendar) startDate.clone();  
  cursor.add(Calendar.DAY_OF_YEAR, presumedDays);  
  long instant = cursor.getTimeInMillis();  
  if (instant == endInstant)  
    return presumedDays;

  final int step = instant < endInstant ? 1 : -1;  
  do {  
    cursor.add(Calendar.DAY_OF_MONTH, step);  
    presumedDays += step;  
  } while (cursor.getTimeInMillis() != endInstant);  
  return presumedDays;  
}
Mad_troll
quelle
4
Die zweite Methode ist falsch, die endgültige whilesollte sein. while (cursor.getTimeInMillis() <= endInstant); Andernfalls erhalten Sie eine Endlosschleife, wenn Sie weniger als einen Tag unterwegs sind.
Chris.Jenkins
Aus dem Kommentar im Link "Sie sollten sich bewusst sein, dass der angegebene Algorithmus möglicherweise" einen Tag mehr "als erwartet ergibt. Er gibt 1 als Anzahl der Tage zwischen dem 28.02.2009, 19:00:00 und dem 28.02.2009 an 19:00:01. "
Zyoo
16

java.time

Verwenden Sie in Java 8 und höher das java.time-Framework ( Tutorial ).

Duration

Die DurationKlasse repräsentiert eine Zeitspanne als Anzahl von Sekunden plus einem Bruchteil einer Sekunde. Es kann Tage, Stunden, Minuten und Sekunden zählen.

ZonedDateTime now = ZonedDateTime.now();
ZonedDateTime oldDate = now.minusDays(1).minusMinutes(10);
Duration duration = Duration.between(oldDate, now);
System.out.println(duration.toDays());

ChronoUnit

Wenn Sie nur die Anzahl der Tage benötigen, können Sie alternativ die Aufzählung verwenden . Beachten Sie, dass die Berechnungsmethoden eher ein als zurückgeben .ChronoUnit longint

long days = ChronoUnit.DAYS.between( then, now );
Vitalii Fedorenko
quelle
Stellen Sie außerdem sicher, dass Sie die Daten in der richtigen Reihenfolge an ChronoUnit.DAYS.between übergeben. Andernfalls wird das Ergebnis zurückgegeben
RRR_J
13

Es hängt davon ab, was Sie als Unterschied definieren. Um zwei Daten um Mitternacht zu vergleichen, können Sie dies tun.

long day1 = ...; // in milliseconds.
long day2 = ...; // in milliseconds.
long days = (day2 - day1) / 86400000;
Peter Lawrey
quelle
9
Dieser Code berücksichtigt nicht die Sommerzeit, daher ist das Ergebnis möglicherweise nicht korrekt.
Johanna
@ Johanna Diese Lösung funktioniert mit DST. Wenn nach der Division eine Runde angewendet wird, wird dieser Unterschied ignoriert und das Ergebnis ist in Ordnung.
Angelcervera
1
@angelcervera Die meiste Zeit wird es korrekt sein, aber wenn es nahe ist, könnte die zusätzliche Stunde die Genauigkeit +/- 1 Tag frei machen (dh es würde den falschen Weg abrunden).
Muhd
3
@ Muhd ​​Ja, du hast recht. Die dritte Zeile muss lauten: lange Tage = Math.round ((Tag2 - Tag1) / 86400000D); Es ist sehr wichtig, dass der Divisor ein doppelter Wert war.
Angelcervera
3
Es tut uns leid. Ich habe heute Morgen vergessen, mein Mathematikmodul der ersten Klasse in mein Gehirn einzustecken. Ich dachte, das Subtrahieren eines Negativs würde die Berechnung beeinträchtigen. Wir sollten in der Lage sein, Kommentare abzustimmen.
Snekse
13
import java.util.Calendar;
import java.util.Date;

public class Main {
    public static long calculateDays(String startDate, String endDate)
    {
        Date sDate = new Date(startDate);
        Date eDate = new Date(endDate);
        Calendar cal3 = Calendar.getInstance();
        cal3.setTime(sDate);
        Calendar cal4 = Calendar.getInstance();
        cal4.setTime(eDate);
        return daysBetween(cal3, cal4);
    }

    public static void main(String[] args) {
        System.out.println(calculateDays("2012/03/31", "2012/06/17"));

    }

    /** Using Calendar - THE CORRECT WAY**/
    public static long daysBetween(Calendar startDate, Calendar endDate) {
        Calendar date = (Calendar) startDate.clone();
        long daysBetween = 0;
        while (date.before(endDate)) {
            date.add(Calendar.DAY_OF_MONTH, 1);
            daysBetween++;
        }
        return daysBetween;
    }
}
Soumyarup Dasgupta
quelle
1
Loop ist keine ausgezeichnete Idee. Wie wäre es mit Leistung, wenn es einfachere Optionen gibt, um dasselbe zu tun?
Angelcervera
1
Eine Leistungsverbesserung besteht darin, um Potenzen von 2 zu erhöhen. Wenn dann das Bedingungsdatum vor (endDate) falsch ist, kehren Sie zur vorherigen Iteration zurück und setzen Sie den Inkrementor auf 1 zurück. Wenn Sie also eine Milliarde Tage entfernt sind, sind Sie es würde vielleicht 30 Iterationen anstelle einer Milliarde machen. Sie könnten die Leistung auch verbessern, indem Sie eine Vermutung anstellen, indem Sie die Millisekunden überprüfen. Dies wäre jedoch wahrscheinlich weniger elegant.
Muhd
9

Lösung unter Verwendung der Differenz zwischen Millisekunden und korrekter Rundung für Sommerzeitdaten:

public static long daysDiff(Date from, Date to) {
    return daysDiff(from.getTime(), to.getTime());
}

public static long daysDiff(long from, long to) {
    return Math.round( (to - from) / 86400000D ); // 1000 * 60 * 60 * 24
}

Ein Hinweis: Natürlich müssen die Daten in einer bestimmten Zeitzone liegen.

Der wichtige Code:

Math.round( (to - from) / 86400000D )

Wenn Sie keine Runde möchten, können Sie UTC-Daten verwenden.

Angelcervera
quelle
1
@marcolopes Nein, gibt 32 zurück. System.out.println (daysDiff (neues Datum (2014, 2, 1), neues Datum (2014, 3, 2))); Seien Sie vorsichtig, denn Januar ist 0.
Angelcervera
4

Illustration des Problems: (Mein Code berechnet Delta in Wochen, aber das gleiche Problem gilt für Delta in Tagen.)

Hier ist eine sehr vernünftig aussehende Implementierung:

public static final long MILLIS_PER_WEEK = 7L * 24L * 60L * 60L * 1000L;

static public int getDeltaInWeeks(Date latterDate, Date earlierDate) {
    long deltaInMillis = latterDate.getTime() - earlierDate.getTime();
    int deltaInWeeks = (int)(deltaInMillis / MILLIS_PER_WEEK);
    return deltaInWeeks; 
}

Aber dieser Test wird fehlschlagen:

public void testGetDeltaInWeeks() {
    delta = AggregatedData.getDeltaInWeeks(dateMar09, dateFeb23);
    assertEquals("weeks between Feb23 and Mar09", 2, delta);
}

Der Grund ist:

Mo März 09 00:00:00 EDT 2009 = 1.236.571.200.000
Mo 23. Februar 00:00:00 EST 2009 = 1.235.365.200.000
MillisPerWeek = 604.800.000
Somit ist
( März 09 - Februar 23 ) / MillisPerWeek =
1.206.000.000 / 604.800.000 = 1.994 ...

Aber jeder, der sich einen Kalender ansieht, würde zustimmen, dass die Antwort 2 ist.

KennethB
quelle
1
Beachten Sie EDT und EST . Sie betrachten die Sommerzeit. 168 Stunden in einer Woche (+1 für das "Gewinnen" einer Stunde im Frühjahr) * zwei Wochen, zusätzlich zur zusätzlichen Sommerzeit, und Sie haben: 335/168 = 1,9940476190.
Jpswain
3

Ich benutze diese Funktion:

DATEDIFF("31/01/2016", "01/03/2016") // me return 30 days

meine Funktion:

import java.util.Date;

public long DATEDIFF(String date1, String date2) {
        long MILLISECS_PER_DAY = 24 * 60 * 60 * 1000;
        long days = 0l;
        SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy"); // "dd/MM/yyyy HH:mm:ss");

        Date dateIni = null;
        Date dateFin = null;        
        try {       
            dateIni = (Date) format.parse(date1);
            dateFin = (Date) format.parse(date2);
            days = (dateFin.getTime() - dateIni.getTime())/MILLISECS_PER_DAY;                        
        } catch (Exception e) {  e.printStackTrace();  }   

        return days; 
     }
Cesin
quelle
2

Schauen Sie sich die getFragmentInDays- Methoden in dieser Apache Commons-Lang-Klasse an DateUtils.

ccpizza
quelle
2

Basierend auf der Antwort von @ Mad_Troll habe ich diese Methode entwickelt.

Ich habe ungefähr 30 Testfälle dagegen ausgeführt, ist die einzige Methode, die Fragmente von Subtageszeit korrekt behandelt.

Beispiel: Wenn Sie jetzt und jetzt + 1 Millisekunde vergehen, ist dies immer noch der gleiche Tag. Tun 1-1-13 23:59:59.098zu1-1-13 23:59:59.099 Renditen 0 Tage, richtig; Alle anderen hier veröffentlichten Methoden führen dies nicht korrekt aus.

Es ist erwähnenswert, dass es egal ist, wie Sie sie eingeben. Wenn Ihr Enddatum vor Ihrem Startdatum liegt, zählt es rückwärts.

/**
 * This is not quick but if only doing a few days backwards/forwards then it is very accurate.
 *
 * @param startDate from
 * @param endDate   to
 * @return day count between the two dates, this can be negative if startDate is after endDate
 */
public static long daysBetween(@NotNull final Calendar startDate, @NotNull final Calendar endDate) {

    //Forwards or backwards?
    final boolean forward = startDate.before(endDate);
    // Which direction are we going
    final int multiplier = forward ? 1 : -1;

    // The date we are going to move.
    final Calendar date = (Calendar) startDate.clone();

    // Result
    long daysBetween = 0;

    // Start at millis (then bump up until we go back a day)
    int fieldAccuracy = 4;
    int field;
    int dayBefore, dayAfter;
    while (forward && date.before(endDate) || !forward && endDate.before(date)) {
        // We start moving slowly if no change then we decrease accuracy.
        switch (fieldAccuracy) {
            case 4:
                field = Calendar.MILLISECOND;
                break;
            case 3:
                field = Calendar.SECOND;
                break;
            case 2:
                field = Calendar.MINUTE;
                break;
            case 1:
                field = Calendar.HOUR_OF_DAY;
                break;
            default:
            case 0:
                field = Calendar.DAY_OF_MONTH;
                break;
        }
        // Get the day before we move the time, Change, then get the day after.
        dayBefore = date.get(Calendar.DAY_OF_MONTH);
        date.add(field, multiplier);
        dayAfter = date.get(Calendar.DAY_OF_MONTH);

        // This shifts lining up the dates, one field at a time.
        if (dayBefore == dayAfter && date.get(field) == endDate.get(field))
            fieldAccuracy--;
        // If day has changed after moving at any accuracy level we bump the day counter.
        if (dayBefore != dayAfter) {
            daysBetween += multiplier;
        }
    }
    return daysBetween;
}

Sie können die @NotNullAnmerkungen entfernen . Diese werden von Intellij verwendet, um Code-Analysen im laufenden Betrieb durchzuführen

Chris.Jenkins
quelle
Ich berücksichtige Millis, diesen Rechner nicht, ich gehe davon aus, dass er die Zahlen auf 0 abrundet. Wie ich oben in der Antwort angegeben habe. Reduzieren Sie Ihre Stunden / Minuten / Sekunden / Millis und Sie werden feststellen, dass es dann richtig zählt.
Chris.Jenkins
1

Sie sagen, dass es "in einem eigenständigen Programm gut funktioniert", aber dass Sie "ungewöhnliche Differenzwerte" erhalten, wenn Sie "dies in meine Logik aufnehmen, um aus dem Bericht zu lesen". Dies deutet darauf hin, dass Ihr Bericht einige Werte enthält, für die er nicht ordnungsgemäß funktioniert, und dass Ihr eigenständiges Programm diese Werte nicht enthält. Anstelle eines eigenständigen Programms schlage ich einen Testfall vor. Schreiben Sie einen Testfall wie ein eigenständiges Programm, das aus der TestCase-Klasse von JUnit stammt. Jetzt können Sie ein ganz bestimmtes Beispiel ausführen und wissen, welchen Wert Sie erwarten (und ihn heute nicht für den Testwert angeben, da sich der heutige Wert im Laufe der Zeit ändert). Wenn Sie die Werte eingeben, die Sie im Standalone-Programm verwendet haben, werden Ihre Tests wahrscheinlich bestanden. Das ist großartig - Sie möchten, dass diese Fälle weiter funktionieren. Fügen Sie jetzt einen Wert aus Ihrem Bericht hinzu, der nicht funktioniert. nicht richtig arbeiten. Ihr neuer Test wird wahrscheinlich fehlschlagen. Finden Sie heraus, warum es fehlschlägt, beheben Sie es und werden Sie grün (alle Tests bestanden). Führen Sie Ihren Bericht aus. Sehen Sie, was noch kaputt ist. schreibe einen Test; lass es passieren. Bald werden Sie feststellen, dass Ihr Bericht funktioniert.

Carl Manaster
quelle
1

Hundert Codezeilen für diese Grundfunktion ???

Nur eine einfache Methode:

protected static int calculateDayDifference(Date dateAfter, Date dateBefore){
    return (int)(dateAfter.getTime()-dateBefore.getTime())/(1000 * 60 * 60 * 24); 
    // MILLIS_IN_DAY = 1000 * 60 * 60 * 24;
}
joro
quelle
5
Ignoriert Zeitzonen. Ignoriert die Sommerzeit und andere Anomalien. Ignoriert das Runden von Teiltagen.
Basil Bourque
1
public static int getDifferenceIndays(long timestamp1, long timestamp2) {
    final int SECONDS = 60;
    final int MINUTES = 60;
    final int HOURS = 24;
    final int MILLIES = 1000;
    long temp;
    if (timestamp1 < timestamp2) {
        temp = timestamp1;
        timestamp1 = timestamp2;
        timestamp2 = temp;
    }
    Calendar startDate = Calendar.getInstance(TimeZone.getDefault());
    Calendar endDate = Calendar.getInstance(TimeZone.getDefault());
    endDate.setTimeInMillis(timestamp1);
    startDate.setTimeInMillis(timestamp2);
    if ((timestamp1 - timestamp2) < 1 * HOURS * MINUTES * SECONDS * MILLIES) {
        int day1 = endDate.get(Calendar.DAY_OF_MONTH);
        int day2 = startDate.get(Calendar.DAY_OF_MONTH);
        if (day1 == day2) {
            return 0;
        } else {
            return 1;
        }
    }
    int diffDays = 0;
    startDate.add(Calendar.DAY_OF_MONTH, diffDays);
    while (startDate.before(endDate)) {
        startDate.add(Calendar.DAY_OF_MONTH, 1);
        diffDays++;
    }
    return diffDays;
}
user1091978
quelle
1

ThreeTen-Extra

Die Antwort von Vitalii Fedorenko ist richtig und beschreibt, wie diese Berechnung auf moderne Weise mit in Java 8 und höher integrierten Java.time- Klassen ( Duration& ChronoUnit) durchgeführt wird (und auf Java 6 & 7 und Android zurückportiert wird ).

Days

Wenn Sie routinemäßig mehrere Tage in Ihrem Code verwenden, können Sie bloße Ganzzahlen durch die Verwendung einer Klasse ersetzen. Die DaysKlasse befindet sich im ThreeTen-Extra- Projekt, einer Erweiterung von java.time und als Grundlage für mögliche zukünftige Ergänzungen von java.time. Die DaysKlasse bietet eine typsichere Möglichkeit, eine Anzahl von Tagen in Ihrer Anwendung darzustellen. Die Klasse enthält geeignete Konstanten für ZEROundONE .

java.util.DateKonvertieren Sie die alten veralteten Objekte in der Frage zunächst in moderne java.time.InstantObjekte. Die alten Datums- / Uhrzeitklassen haben neu hinzugefügte Methoden, um die Konvertierung in java.time zu erleichtern, z java.util.Date::toInstant.

Instant start = utilDateStart.toInstant(); // Inclusive.
Instant stop = utilDateStop.toInstant();  // Exclusive.

Übergeben Sie beide InstantObjekte an die Factory-Methode fürorg.threeten.extra.Days .

In der aktuellen Implementierung (2016-06) ist dies ein Wrapper-Aufruf. Weitere Informationen finden java.time.temporal.ChronoUnit.DAYS.betweenSie im ChronoUnitKlassendokument. Um es klar auszudrücken : Alle Großbuchstaben DAYSsind in der Aufzählung enthalten, ChronoUnitwährend Initial-Cap Dayseine Klasse von ThreeTen-Extra ist.

Days days = Days.between( start , stop );

Sie können diese DaysObjekte um Ihren eigenen Code herum übergeben. Sie können durch Aufrufen zu einem String im Standardformat ISO 8601 serialisieren toString. Dieses Format PnDverwendet a P, um den Anfang zu markieren, und Dbedeutet "Tage" mit einer Anzahl von Tagen dazwischen. Sowohl die java.time-Klassen als auch ThreeTen-Extra verwenden diese Standardformate standardmäßig, wenn Zeichenfolgen generiert und analysiert werden, die Datums- und Uhrzeitwerte darstellen.

String output = days.toString();

P3D

Days days = Days.parse( "P3D" );  
Basil Bourque
quelle
0

Dieser Code berechnet Tage zwischen 2 Datumszeichenfolgen:

    static final long MILLI_SECONDS_IN_A_DAY = 1000 * 60 * 60 * 24;
    static final String DATE_FORMAT = "dd-MM-yyyy";
    public long daysBetween(String fromDateStr, String toDateStr) throws ParseException {
    SimpleDateFormat format = new SimpleDateFormat(DATE_FORMAT);
    Date fromDate;
    Date toDate;
    fromDate = format.parse(fromDateStr);
    toDate = format.parse(toDateStr);
    return (toDate.getTime() - fromDate.getTime()) / MILLI_SECONDS_IN_A_DAY;
}
Kayvan Tehrani
quelle
0

Wenn Sie nach einer Lösung suchen, die die richtige Anzahl oder Tage zwischen z. B. 11/30/2014 23:59und 12/01/2014 00:01der folgenden Lösung mit Joda Time zurückgibt .

private int getDayDifference(long past, long current) {
    DateTime currentDate = new DateTime(current);
    DateTime pastDate = new DateTime(past);
    return currentDate.getDayOfYear() - pastDate.getDayOfYear();
} 

Diese Implementierung wird 1als Differenz in Tagen zurückgegeben. Die meisten der hier veröffentlichten Lösungen berechnen die Differenz in Millisekunden zwischen zwei Daten. 0Dies bedeutet, dass dies zurückgegeben wird, da zwischen diesen beiden Daten nur ein Unterschied von 2 Minuten besteht.

Tomrozb
quelle
0

Sie sollten die Joda-Zeitbibliothek verwenden, da Java Util Date manchmal falsche Werte zurückgibt.

Joda vs Java Util Date

Zum Beispiel Tage zwischen gestern (TT-MM-JJJJ, 12-07-2016) und dem ersten Tag des Jahres 1957 (TT-MM-JJJJ, 01-01-1957):

public class Main {

public static void main(String[] args) {
    SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyyy");

    Date date = null;
    try {
        date = format.parse("12-07-2016");
    } catch (ParseException e) {
        e.printStackTrace();
    }

    //Try with Joda - prints 21742
    System.out.println("This is correct: " + getDaysBetweenDatesWithJodaFromYear1957(date));
    //Try with Java util - prints 21741
    System.out.println("This is not correct: " + getDaysBetweenDatesWithJavaUtilFromYear1957(date));    
}


private static int getDaysBetweenDatesWithJodaFromYear1957(Date date) {
    DateTime jodaDateTime = new DateTime(date);
    DateTimeFormatter formatter = DateTimeFormat.forPattern("dd-MM-yyyy");
    DateTime y1957 = formatter.parseDateTime("01-01-1957");

    return Days.daysBetween(y1957 , jodaDateTime).getDays();
}

private static long getDaysBetweenDatesWithJavaUtilFromYear1957(Date date) {
    SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyyy");

    Date y1957 = null;
    try {
        y1957 = format.parse("01-01-1957");
    } catch (ParseException e) {
        e.printStackTrace();
    }

    return TimeUnit.DAYS.convert(date.getTime() - y1957.getTime(), TimeUnit.MILLISECONDS);
}

Daher rate ich Ihnen wirklich, die Joda Time-Bibliothek zu verwenden.

Šime Tokić
quelle
1
Zu Ihrer Information : Während Joda-Time weiterhin aktiv unterstützt wird, empfiehlt das Entwicklungsteam die Migration zu java.time . Um von ihrer Homepage zu zitieren: "Joda-Time ist die de facto Standard-Datums- und Zeitbibliothek für Java vor Java SE 8. Benutzer werden nun aufgefordert, auf java.time (JSR-310) zu migrieren."
Basil Bourque
-6

Ich habe es so gemacht. es ist einfach :)

Date d1 = jDateChooserFrom.getDate();
Date d2 = jDateChooserTo.getDate();

Calendar day1 = Calendar.getInstance();
day1.setTime(d1);

Calendar day2 = Calendar.getInstance();
day2.setTime(d2);

int from = day1.get(Calendar.DAY_OF_YEAR);
int to = day2.get(Calendar.DAY_OF_YEAR);

int difference = to-from;
Dayadra Lakmal
quelle
4
Führen Sie einige Tests durch. Sie werden sehr schnell feststellen, dass dies nicht funktioniert. Machen Sie vom 31. Dezember 2013 bis zum 1. Januar 2014 einen Tagesunterschied, oder? Ihre Berechnung reicht aus, 1 - 365 = -364. Was mit Sicherheit nicht richtig ist.
Chris.Jenkins