it-swarm.com.de

Berechnung der Differenz zwischen zwei Java-Datumsinstanzen

Ich verwende die Java.util.Date-Klasse von Java in Scala und möchte ein Date-Objekt und die aktuelle Uhrzeit vergleichen. Ich weiß, dass ich das Delta mithilfe von getTime () berechnen kann:

(new Java.util.Date()).getTime() - oldDate.getTime()

Es bleibt mir jedoch nur eine long, die Millisekunden darstellt. Gibt es eine einfachere und schönere Methode, um ein Zeitdelta zu erhalten?

377
pr1001

Die JDK Date API ist leider schrecklich kaputt. Ich empfehle die Verwendung von Joda Time Library .

Joda Time hat ein Zeitkonzept Intervall :

Interval interval = new Interval(oldTime, new Instant());

BEARBEITEN: Joda hat übrigens zwei Konzepte: Interval zur Darstellung eines Zeitintervalls zwischen zwei Zeitpunkten (repräsentieren Sie die Zeit zwischen 8 und 10 Uhr) und eine Duration, die eine Zeitdauer ohne die tatsächlichen Zeitgrenzen darstellt (z. B. zwei Stunden) !)

Wenn Sie sich nur für Zeitvergleiche interessieren, implementieren die meisten Date-Implementierungen (einschließlich der JDK-Implementierung) die Comparable-Schnittstelle, mit der Sie die Comparable.compareTo() verwenden können.

177
notnoop

Einfacher Unterschied (ohne lib)

/**
 * Get a diff between two dates
 * @param date1 the oldest date
 * @param date2 the newest date
 * @param timeUnit the unit in which you want the diff
 * @return the diff value, in the provided unit
 */
public static long getDateDiff(Date date1, Date date2, TimeUnit timeUnit) {
    long diffInMillies = date2.getTime() - date1.getTime();
    return timeUnit.convert(diffInMillies,TimeUnit.MILLISECONDS);
}

Und dann kannst du anrufen:

getDateDiff(date1,date2,TimeUnit.MINUTES);

um den Unterschied der 2 Datumsangaben in Minuten zu erhalten.

TimeUnit ist Java.util.concurrent.TimeUnit, eine Standard-Java-Enumeration, die von Nanos bis Tagen reicht.


Von Menschen lesbarer Diff (ohne lib)

public static Map<TimeUnit,Long> computeDiff(Date date1, Date date2) {

    long diffInMillies = date2.getTime() - date1.getTime();

    //create the list
    List<TimeUnit> units = new ArrayList<TimeUnit>(EnumSet.allOf(TimeUnit.class));
    Collections.reverse(units);

    //create the result map of TimeUnit and difference
    Map<TimeUnit,Long> result = new LinkedHashMap<TimeUnit,Long>();
    long milliesRest = diffInMillies;

    for ( TimeUnit unit : units ) {

        //calculate difference in millisecond 
        long diff = unit.convert(milliesRest,TimeUnit.MILLISECONDS);
        long diffInMilliesForUnit = unit.toMillis(diff);
        milliesRest = milliesRest - diffInMilliesForUnit;

        //put the result in the map
        result.put(unit,diff);
    }

    return result;
}

http://ideone.com/5dXeu6

Die Ausgabe ist in etwa Map:{DAYS=1, HOURS=3, MINUTES=46, SECONDS=40, MILLISECONDS=0, MICROSECONDS=0, NANOSECONDS=0}, wobei die Einheiten bestellt werden.

Sie müssen diese Karte nur in eine benutzerfreundliche Zeichenfolge konvertieren.


Warnung

Die obigen Codeausschnitte berechnen einen einfachen Unterschied zwischen zwei Zeitpunkten. Es kann zu Problemen bei einer Sommerzeitumstellung führen, wie in diesem Beitrag erläutert. Dies bedeutet, wenn Sie die Differenz zwischen Datumsangaben berechnen, ohne dass ein Tag/eine Stunde fehlt.

Meiner Meinung nach ist der Datumsunterschied subjektiv, besonders an Tagen. Du darfst:

  • zählen Sie die verstrichene Zeit von 24 Stunden: Tag + 1 - Tag = 1 Tag = 24h

  • zählen Sie die verstrichene Zeit und achten Sie auf die Sommerzeit: Tag + 1 - Tag = 1 = 24 Stunden (bei Verwendung der Mitternachtszeit und Sommerzeit können es jedoch 0 Tage und 23 Stunden sein)

  • zähle die Anzahl von day switches, was Tag + 1 um 1 Uhr bedeutet - Tag 11 Uhr = 1 Tag, auch wenn die abgelaufene Zeit nur 2 Stunden beträgt (oder 1 Stunde, wenn Sommerzeit gilt: p)

Meine Antwort ist gültig, wenn Ihre Definition von Datumsunterschieden an Tagen mit dem 1. Fall übereinstimmt

Mit JodaTime

Wenn Sie JodaTime verwenden, können Sie das diff für 2 Zeitpunkte (von Millies gesicherte ReadableInstant) -Daten abrufen mit:

Interval interval = new Interval(oldInstant, new Instant());

Sie können jedoch auch den Unterschied für Ortsdaten/-zeiten ermitteln:

// returns 4 because of the leap year of 366 days
new Period(LocalDate.now(), LocalDate.now().plusDays(365*5), PeriodType.years()).getYears() 

// this time it returns 5
new Period(LocalDate.now(), LocalDate.now().plusDays(365*5+1), PeriodType.years()).getYears() 

// And you can also use these static methods
Years.yearsBetween(LocalDate.now(), LocalDate.now().plusDays(365*5)).getYears()
489
int diffInDays = (int)( (newerDate.getTime() - olderDate.getTime()) 
                 / (1000 * 60 * 60 * 24) )

Beachten Sie, dass dies mit UTC-Datumsangaben funktioniert. Wenn Sie sich lokale Datumsangaben ansehen, kann der Unterschied daher ein Tag sein. Um korrekt mit lokalen Datumsangaben zu arbeiten, ist aufgrund der Sommerzeit ein völlig anderer Ansatz erforderlich.

147

Sie müssen Ihr Problem klarer definieren. Sie könnten nehmen einfach die Anzahl der Millisekunden zwischen den beiden Date-Objekten und dividieren sie beispielsweise durch die Anzahl der Millisekunden in 24 Stunden ... aber:

  • Zeitzonen werden dabei nicht berücksichtigt - Date ist immer in UTC
  • Die Sommerzeit wird dabei nicht berücksichtigt (zB Tage, die nur 23 Stunden lang sind).
  • Wie viele Tage gibt es sogar innerhalb von UTC am 16. August von 23 Uhr bis 18. August um 2 Uhr? Es sind nur 27 Stunden, bedeutet das einen Tag? Oder sollten es drei Tage sein, weil es drei Termine umfasst?
53
Jon Skeet

Verwenden des in Java 8+ integrierten Java.time - Frameworks:

ZonedDateTime now = ZonedDateTime.now();
ZonedDateTime oldDate = now.minusDays(1).minusMinutes(10);
Duration duration = Duration.between(oldDate, now);
System.out.println("ISO-8601: " + duration);
System.out.println("Minutes: " + duration.toMinutes());

Ausgabe: 

ISO-8601: PT24H10M

Minuten: 1450

Weitere Informationen finden Sie im Oracle Tutorial und dem ISO 8601 Standard.

45

tl; dr

Konvertieren Sie Ihre veralteten Java.util.Date-Objekte in ihre Ersetzung Java.time.Instant. Berechnen Sie dann die verstrichene Zeit als Duration.

Duration d = 
    Duration.between(                   // Calculate the span of time between two moments as a number of hours, minutes, and seconds.
        myJavaUtilDate.toInstant() ,    // Convert legacy class to modern class by calling new method added to the old class.
        Instant.now()                   // Capture the current moment in UTC. About two and a half hours later in this example.
    )
;

d.toString (): PT2H34M56S

d.toMinutes (): 154

d.toMinutesPart (): 34

ISO 8601 Format: PnYnMnDTnHnMnS

Die sinnvolle Norm ISO 8601 definiert eine kurze textuelle Darstellung einer Zeitspanne als Anzahl von Jahren, Monaten, Tagen, Stunden usw. Die Norm nennt eine solche Zeitspanne eine Dauer . Das Format ist PnYnMnDTnHnMnS, wobei P "Periode" bedeutet, die T den Datumsteil vom Zeitteil trennt und dazwischen Zahlen sind, auf die ein Buchstabe folgt.

Beispiele:

  • P3Y6M4DT12H30M5S
    drei Jahre, sechs Monate, vier Tage, zwölf Stunden, dreißig Minuten und fünf Sekunden
  • PT4H30M
    Viereinhalb Stunden

Java.time

Das in Java 8 und später integrierte Java.time - Framework ersetzt die störenden alten Java.util.DateJava.util.Calendar-Klassen. Die neuen Klassen sind vom sehr erfolgreichen Joda-Time Framework inspiriert, das als Nachfolger gedacht ist, im Konzept ähnlich ist, aber neu gestaltet wurde. Definiert durch JSR 310 . Erweitert um das Projekt ThreeTen-Extra . Siehe das Tutorial .

Moment

Die Instant Klasse repräsentiert einen Moment auf der Timeline in UTC mit einer Auflösung von Nanosekunden (bis zu neun (9) Ziffern eines Dezimalbruchs). 

Instant instant = Instant.now() ;  // Capture current moment in UTC.

Vermeiden Sie am besten die älteren Klassen wie Date/Calendar. Wenn Sie jedoch mit altem Code, der noch nicht auf Java.time aktualisiert wurde, interoperieren müssen, konvertieren Sie ihn hin und her. Rufen Sie neue Konvertierungsmethoden auf, die den alten Klassen hinzugefügt wurden. Um von einem Java.util.Date zu einer Instant zu wechseln, rufen Sie Date::toInstant auf. 

Instant instant = myJavaUtilDate.toInstant() ;  // Convert from legacy `Java.util.Date` class to modern `Java.time.Instant` class.

Zeitspanne

Die Java.time-Klassen haben diese Idee der Darstellung einer Zeitspanne als Anzahl von Jahren, Monaten, Tagen, Stunden, Minuten, Sekunden in zwei Hälften aufgeteilt:

  • Period für Jahre, Monate, Tage
  • Duration für Tage, Stunden, Minuten, Sekunden

Hier ist ein Beispiel.

ZoneId zoneId = ZoneId.of ( "America/Montreal" );
ZonedDateTime now = ZonedDateTime.now ( zoneId );
ZonedDateTime future = now.plusMinutes ( 63 );
Duration duration = Duration.between ( now , future );

Auf die Konsole ausgeben.

Sowohl Period als auch Duration verwenden den Standard ISO 8601 , um eine String-Darstellung ihres Werts zu erstellen.

System.out.println ( "now: " + now + " to future: " + now + " = " + duration );

jetzt: 2015-11-26T00: 46: 48.016-05: 00 [America/Montreal] zur Zukunft: 2015-11-26T00: 46: 48.016-05: 00 [America/Montreal] = PT1H3M

Java 9 fügt Duration Methoden hinzu, um den Tagteil, den Stundenabschnitt, den Minutenabschnitt und den Sekundenabschnitt abzurufen.

Sie können die Gesamtzahl der Tage oder Stunden oder Minuten oder Sekunden oder Millisekunden oder Nanosekunden während der gesamten Dauer abrufen.

long totalHours = duration.toHours();

In Java 9 erhält die Klasse Duration neue Methoden , um die verschiedenen Teile von Tagen, Stunden, Minuten, Sekunden, Millisekunden/Nanosekunden zurückzugeben. Rufen Sie die to…Part-Methoden auf: toDaysPart(), toHoursPart() usw.

ChronoUnit

Wenn Sie sich nur für eine einfachere größere Granularität der Zeit interessieren, z. B. "Anzahl der verstrichenen Tage", verwenden Sie die Enumeration ChronoUnit .

long daysElapsed = ChronoUnit.DAYS.between( earlier , later );

Ein anderes Beispiel.

Instant now = Instant.now();
Instant later = now.plus( Duration.ofHours( 2 ) );
…
long minutesElapsed = ChronoUnit.MINUTES.between( now , later );

120


Über Java.time

Das Java.time -Framework ist in Java 8 und höher integriert. Diese Klassen ersetzen die lästigen alten Legacy Date-Time-Klassen wie Java.util.Date , Calendar , & SimpleDateFormat .

Das Joda-Time -Projekt, jetzt im Wartungsmodus , empfiehlt die Migration zu Java.time.

Weitere Informationen finden Sie im Oracle Tutorial . In Stack Overflow finden Sie viele Beispiele und Erklärungen. Spezifikation ist JSR 310 .

Wo erhalten Sie die Java.time-Klassen? 

  • _/Java SE 8 und SE 9 und später
    • Eingebaut. 
    • Teil der Standard-Java-API mit einer mitgelieferten Implementierung.
    • Java 9 fügt einige kleinere Funktionen und Korrekturen hinzu.
  • Java SE 6 und SE 7
    • Ein Großteil der Java.time-Funktionalität wird in ThreeTen-Backport auf Java 6 & 7 zurückportiert.
  • Android

Das ThreeTen-Extra -Projekt erweitert Java.time um zusätzliche Klassen. Dieses Projekt ist ein Testfeld für mögliche zukünftige Erweiterungen von Java.time. Hier finden Sie einige nützliche Klassen, wie zum Beispiel Interval , YearWeek , YearQuarter und more .


Joda-Zeit

UPDATE: Das Projekt Joda-Time befindet sich jetzt im Wartungsmodus , wobei das Team die Migration zu den Java.time -Klassen empfiehlt. Ich lasse diesen Abschnitt für die Geschichte unberührt.

Die Joda-Time-Bibliothek verwendet ISO 8601 für ihre Standardeinstellungen. Die Period-Klasse analysiert und generiert diese PnYnMnDTnHnMnS-Zeichenfolgen.

DateTime now = DateTime.now(); // Caveat: Ignoring the important issue of time zones.
Period period = new Period( now, now.plusHours( 4 ).plusMinutes( 30));
System.out.println( "period: " + period );

Macht:

period: PT4H30M
39
Basil Bourque
Days d = Days.daysBetween(startDate, endDate);
int days = d.getDays();

https://www.joda.org/joda-time/faq.html#datediff

34
Adriano Bacha

Eine etwas einfachere Alternative: 

System.currentTimeMillis() - oldDate.getTime()

Was "schöner" ist: Nun, was genau brauchst du? Das Problem beim Darstellen von Zeitdauern als Anzahl von Stunden und Tagen usw. besteht darin, dass es aufgrund der Komplexität von Datumsangaben zu Ungenauigkeiten und falschen Erwartungen führen kann (beispielsweise können Tage aufgrund der Sommerzeit 23 oder 25 Stunden betragen).

24

Die Verwendung des Millisekunden-Ansatzes kann in einigen Gebieten zu Problemen führen.

Nehmen wir beispielsweise an, die Differenz zwischen den beiden Terminen 24.03.2007 und 25.03.2007 sollte 1 Tag sein. 

Wenn Sie jedoch die Millisekunden-Route verwenden, erhalten Sie 0 Tage, wenn Sie diese in Großbritannien ausführen. 

/** Manual Method - YIELDS INCORRECT RESULTS - DO NOT USE**/  
/* This method is used to find the no of days between the given dates */  
public long calculateDays(Date dateEarly, Date dateLater) {  
   return (dateLater.getTime() - dateEarly.getTime()) / (24 * 60 * 60 * 1000);  
} 

Eine bessere Möglichkeit, dies zu implementieren, ist die Verwendung von Java.util.Calendar

/** 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;  
}  
22
zasadnyy

Es gibt viele Möglichkeiten, den Unterschied zwischen Datum und Uhrzeit zu finden. Eine der einfachsten Möglichkeiten, die ich kenne, wäre:

      Calendar calendar1 = Calendar.getInstance();
      Calendar calendar2 = Calendar.getInstance();
      calendar1.set(2012, 04, 02);
      calendar2.set(2012, 04, 04);
      long milsecs1= calendar1.getTimeInMillis();
      long milsecs2 = calendar2.getTimeInMillis();
      long diff = milsecs2 - milsecs1;
      long dsecs = diff / 1000;
      long dminutes = diff / (60 * 1000);
      long dhours = diff / (60 * 60 * 1000);
      long ddays = diff / (24 * 60 * 60 * 1000);

      System.out.println("Your Day Difference="+ddays);

Die print-Anweisung ist nur ein Beispiel - Sie können sie nach Belieben formatieren.

21
xxxxxxxx d

Da alle Antworten hier richtig sind, aber ältere Java- oder 3rd Party-Bibliotheken wie Joda oder ähnliches verwenden, werde ich in Java 8 und später eine andere Möglichkeit verwenden, neue Java.time - Klassen zu verwenden. Siehe Oracle Tutorial .

Verwenden Sie LocalDate und ChronoUnit :

LocalDate d1 = LocalDate.of(2017, 5, 1);
LocalDate d2 = LocalDate.of(2017, 5, 18);

long days = ChronoUnit.DAYS.between(d1, d2);
System.out.println( days );

Das Abziehen der Datumsangaben in Millisekunden funktioniert (wie in einem anderen Beitrag beschrieben), aber Sie müssen () verwenden, um HOUR_OF_DAY und nicht HOUR zu verwenden, wenn Sie die Zeitbereiche Ihrer Daten löschen:

public static final long MSPERDAY = 60 * 60 * 24 * 1000;
...
final Calendar dateStartCal = Calendar.getInstance();
dateStartCal.setTime(dateStart);
dateStartCal.set(Calendar.HOUR_OF_DAY, 0); // Crucial.
dateStartCal.set(Calendar.MINUTE, 0);
dateStartCal.set(Calendar.SECOND, 0);
dateStartCal.set(Calendar.MILLISECOND, 0);
final Calendar dateEndCal = Calendar.getInstance();
dateEndCal.setTime(dateEnd);
dateEndCal.set(Calendar.HOUR_OF_DAY, 0); // Crucial.
dateEndCal.set(Calendar.MINUTE, 0);
dateEndCal.set(Calendar.SECOND, 0);
dateEndCal.set(Calendar.MILLISECOND, 0);
final long dateDifferenceInDays = ( dateStartCal.getTimeInMillis()
                                  - dateEndCal.getTimeInMillis()
                                  ) / MSPERDAY;
if (dateDifferenceInDays > 15) {
    // Do something if difference > 15 days
}
9

Werfen Sie einen Blick auf Joda Time , eine verbesserte Date/Time-API für Java, die mit Scala gut funktionieren sollte.

8
Rob H

Wenn Sie JodaTime oder ähnliches nicht verwenden möchten, ist dies wahrscheinlich die beste Lösung:

final static long MILLIS_PER_DAY = 24 * 3600 * 1000;
long msDiff= date1.getTime() - date2.getTime();
long daysDiff = Math.round(msDiff / ((double)MILLIS_PER_DAY));

Die Anzahl der Millisekunden pro Tag ist nicht immer gleich (aufgrund von Sommerzeit und Schaltsekunden), aber sie ist sehr nahe und zumindest Abweichungen aufgrund der Sommerzeit werden über längere Zeiträume aufgehoben. Daher wird das Teilen und das Runden dann zu einem korrekten Ergebnis führen (zumindest solange der verwendete lokale Kalender keine anderen Zeitsprünge enthält als DST und Schaltsekunden).

Beachten Sie, dass dabei immer noch davon ausgegangen wird, dass date1 und date2 auf dieselbe Uhrzeit eingestellt sind. Zu unterschiedlichen Tageszeiten müssen Sie zunächst definieren, was "Datumsunterschied" bedeutet, wie Jon Skeet es anmerkt.

8
sleske

Lassen Sie mich einen Unterschied zwischen dem Joda-Intervall und den Tagen zeigen:

DateTime start = new DateTime(2012, 2, 6, 10, 44, 51, 0);
DateTime end = new DateTime(2012, 2, 6, 11, 39, 47, 1);
Interval interval = new Interval(start, end);
Period period = interval.toPeriod();
System.out.println(period.getYears() + " years, " + period.getMonths() + " months, " + period.getWeeks() + " weeks, " + period.getDays() + " days");
System.out.println(period.getHours() + " hours, " + period.getMinutes() + " minutes, " + period.getSeconds() + " seconds ");
//Result is:
//0 years, 0 months, *1 weeks, 1 days*
//0 hours, 54 minutes, 56 seconds 

//Period can set PeriodType,such as PeriodType.yearMonthDay(),PeriodType.yearDayTime()...
Period p = new Period(start, end, PeriodType.yearMonthDayTime());
System.out.println(p.getYears() + " years, " + p.getMonths() + " months, " + p.getWeeks() + " weeks, " + p.getDays() + "days");
System.out.println(p.getHours() + " hours, " + p.getMinutes() + " minutes, " + p.getSeconds() + " seconds ");
//Result is:
//0 years, 0 months, *0 weeks, 8 days*
//0 hours, 54 minutes, 56 seconds 
5
user674158

Wenn Sie eine formatierte Rückgabefolge wie "2 Days 03h 42m 07s" benötigen, versuchen Sie Folgendes:

public String fill2(int value)
{
    String ret = String.valueOf(value);

    if (ret.length() < 2)
        ret = "0" + ret;            
    return ret;
}

public String get_duration(Date date1, Date date2)
{                   
    TimeUnit timeUnit = TimeUnit.SECONDS;

    long diffInMilli = date2.getTime() - date1.getTime();
    long s = timeUnit.convert(diffInMilli, TimeUnit.MILLISECONDS);

    long days = s / (24 * 60 * 60);
    long rest = s - (days * 24 * 60 * 60);
    long hrs = rest / (60 * 60);
    long rest1 = rest - (hrs * 60 * 60);
    long min = rest1 / 60;      
    long sec = s % 60;

    String dates = "";
    if (days > 0) dates = days + " Days ";

    dates += fill2((int) hrs) + "h ";
    dates += fill2((int) min) + "m ";
    dates += fill2((int) sec) + "s ";

    return dates;
}
5
Ingo
public static String getDifferenceBtwTime(Date dateTime) {

    long timeDifferenceMilliseconds = new Date().getTime() - dateTime.getTime();
    long diffSeconds = timeDifferenceMilliseconds / 1000;
    long diffMinutes = timeDifferenceMilliseconds / (60 * 1000);
    long diffHours = timeDifferenceMilliseconds / (60 * 60 * 1000);
    long diffDays = timeDifferenceMilliseconds / (60 * 60 * 1000 * 24);
    long diffWeeks = timeDifferenceMilliseconds / (60 * 60 * 1000 * 24 * 7);
    long diffMonths = (long) (timeDifferenceMilliseconds / (60 * 60 * 1000 * 24 * 30.41666666));
    long diffYears = (long)(timeDifferenceMilliseconds / (1000 * 60 * 60 * 24 * 365));

    if (diffSeconds < 1) {
        return "one sec ago";
    } else if (diffMinutes < 1) {
        return diffSeconds + " seconds ago";
    } else if (diffHours < 1) {
        return diffMinutes + " minutes ago";
    } else if (diffDays < 1) {
        return diffHours + " hours ago";
    } else if (diffWeeks < 1) {
        return diffDays + " days ago";
    } else if (diffMonths < 1) {
        return diffWeeks + " weeks ago";
    } else if (diffYears < 12) {
        return diffMonths + " months ago";
    } else {
        return diffYears + " years ago";
    }
}   
4
Parth Solanki

Ein Beispiel finden Sie hier http://www.roseindia.net/Java/beginners/DateDifferent.shtml .__ Dieses Beispiel gibt Ihnen einen Unterschied in Tagen, Stunden, Minuten, Sekunden und Millisekunden :).

import Java.util.Calendar;
import Java.util.Date;

public class DateDifferent {
    public static void main(String[] args) {
        Date date1 = new Date(2009, 01, 10);
        Date date2 = new Date(2009, 07, 01);
        Calendar calendar1 = Calendar.getInstance();
        Calendar calendar2 = Calendar.getInstance();
        calendar1.setTime(date1);
        calendar2.setTime(date2);
        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.");
    }
}
4
YoK

Folgender Code kann die gewünschte Ausgabe liefern:

String startDate = "Jan 01 2015";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMM dd yyyy");
LocalDate date = LocalDate.parse(startDate, formatter);

String currentDate = "Feb 11 2015";
LocalDate date1 = LocalDate.parse(currentDate, formatter);

System.out.println(date1.toEpochDay() - date.toEpochDay());
4
Vishal Ganjare

Verwenden Sie die GMT-Zeitzone, um eine Instanz des Kalenders abzurufen. Legen Sie die Zeit mithilfe der Set-Methode der Calendar-Klasse fest. In der GMT-Zeitzone sind 0 Offset (nicht wirklich wichtig) und das Sommerzeitflag auf "false" gesetzt.

    final Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));

    cal.set(Calendar.YEAR, 2011);
    cal.set(Calendar.MONTH, 9);
    cal.set(Calendar.DAY_OF_MONTH, 29);
    cal.set(Calendar.HOUR, 0);
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND, 0);
    final Date startDate = cal.getTime();

    cal.set(Calendar.YEAR, 2011);
    cal.set(Calendar.MONTH, 12);
    cal.set(Calendar.DAY_OF_MONTH, 21);
    cal.set(Calendar.HOUR, 0);
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND, 0);
    final Date endDate = cal.getTime();

    System.out.println((endDate.getTime() - startDate.getTime()) % (1000l * 60l * 60l * 24l));
4
Michal
int daysDiff = (date1.getTime() - date2.getTime()) / MILLIS_PER_DAY;
3
Bozho

Am besten ist es

(Date1-Date2)/86 400 000 

Diese Anzahl ist die Anzahl von Millisekunden an einem Tag. 

Ein anderes Datum gibt Ihnen einen Unterschied in Millisekunden. 

Sammeln Sie die Antwort in einer double -Variable.

3
Revanth Kumar

Nur um die erste Frage zu beantworten:

Fügen Sie den folgenden Code in eine Funktion wie Long getAge () {} ein.

Date dahora = new Date();
long MillisToYearsByDiv = 1000l *60l * 60l * 24l * 365l;
long javaOffsetInMillis = 1990l * MillisToYearsByDiv;
long realNowInMillis = dahora.getTime() + javaOffsetInMillis;
long realBirthDayInMillis = this.getFechaNac().getTime() + javaOffsetInMillis;
long ageInMillis = realNowInMillis - realBirthDayInMillis;

return ageInMillis / MillisToYearsByDiv;

Am wichtigsten ist es, beim Multiplizieren und Dividieren mit langen Zahlen zu arbeiten. Und natürlich der Versatz, den Java in seiner Datumsberechnung anwendet.

:)

2

Nachdem Sie alle anderen Antworten durchgeblättert haben, um den Datumstyp von Java 7 zu behalten, aber mit dem Ansatz von Java 8 diff genauer/standardisiert zu sein,

public static long daysBetweenDates(Date d1, Date d2) {
    Instant instant1 = d1.toInstant();
    Instant instant2 = d2.toInstant();
    long diff = ChronoUnit.DAYS.between(instant1, instant2);
    return diff;
}
2
gene b.

Da die Frage mit Scala markiert ist,

import scala.concurrent.duration._
val diff = (System.currentTimeMillis() - oldDate.getTime).milliseconds
val diffSeconds = diff.toSeconds
val diffMinutes = diff.toMinutes
val diffHours = diff.toHours
val diffDays = diff.toDays
2
VasiliNovikov

Nicht die Standard-API verwenden, nein. Sie können Ihre eigene Rolle machen, indem Sie Folgendes tun:

class Duration {
    private final TimeUnit unit;
    private final long length;
    // ...
}

Oder Sie können Joda verwenden:

DateTime a = ..., b = ...;
Duration d = new Duration(a, b);
2
gustafc

Das ist wahrscheinlich der einfachste Weg, dies zu tun - vielleicht liegt es daran, dass ich seit einiger Zeit in Java programmiere (mit seinen zugegebenermaßen unübersichtlichen Datums- und Zeitbibliotheken), aber dieser Code sieht für mich "einfach und schön" aus!

Sind Sie zufrieden mit dem Ergebnis, das in Millisekunden zurückgegeben wird, oder ist ein Teil Ihrer Frage, dass Sie es vorziehen würden, es in einem alternativen Format zurückzugeben?

2
Andrzej Doyle

Hier ist eine korrekte Java 7-Lösung in O(1) ohne Abhängigkeiten.

public static int countDaysBetween(Date date1, Date date2) {

    Calendar c1 = removeTime(from(date1));
    Calendar c2 = removeTime(from(date2));

    if (c1.get(YEAR) == c2.get(YEAR)) {

        return Math.abs(c1.get(DAY_OF_YEAR) - c2.get(DAY_OF_YEAR)) + 1;
    }
    // ensure c1 <= c2
    if (c1.get(YEAR) > c2.get(YEAR)) {
        Calendar c = c1;
        c1 = c2;
        c2 = c;
    }
    int y1 = c1.get(YEAR);
    int y2 = c2.get(YEAR);
    int d1 = c1.get(DAY_OF_YEAR);
    int d2 = c2.get(DAY_OF_YEAR);

    return d2 + ((y2 - y1) * 365) - d1 + countLeapYearsBetween(y1, y2) + 1;
}

private static int countLeapYearsBetween(int y1, int y2) {

    if (y1 < 1 || y2 < 1) {
        throw new IllegalArgumentException("Year must be > 0.");
    }
    // ensure y1 <= y2
    if (y1 > y2) {
        int i = y1;
        y1 = y2;
        y2 = i;
    }

    int diff = 0;

    int firstDivisibleBy4 = y1;
    if (firstDivisibleBy4 % 4 != 0) {
        firstDivisibleBy4 += 4 - (y1 % 4);
    }
    diff = y2 - firstDivisibleBy4 - 1;
    int divisibleBy4 = diff < 0 ? 0 : diff / 4 + 1;

    int firstDivisibleBy100 = y1;
    if (firstDivisibleBy100 % 100 != 0) {
        firstDivisibleBy100 += 100 - (firstDivisibleBy100 % 100);
    }
    diff = y2 - firstDivisibleBy100 - 1;
    int divisibleBy100 = diff < 0 ? 0 : diff / 100 + 1;

    int firstDivisibleBy400 = y1;
    if (firstDivisibleBy400 % 400 != 0) {
        firstDivisibleBy400 += 400 - (y1 % 400);
    }
    diff = y2 - firstDivisibleBy400 - 1;
    int divisibleBy400 = diff < 0 ? 0 : diff / 400 + 1;

    return divisibleBy4 - divisibleBy100 + divisibleBy400;
}


public static Calendar from(Date date) {

    Calendar c = Calendar.getInstance();
    c.setTime(date);

    return c;
}


public static Calendar removeTime(Calendar c) {

    c.set(HOUR_OF_DAY, 0);
    c.set(MINUTE, 0);
    c.set(SECOND, 0);
    c.set(MILLISECOND, 0);

    return c;
}
2
suxumuxu

Hinweis: StartDate und EndDates sind -> Java.util.Date 

import org.joda.time.Duration;
import org.joda.time.Interval;
Interval interval = new Interval(startDate.getTime(), endDate.getTime);
Duration period = interval.toDuration();
period.getStandardDays() //gives the number of days elapsed between start and end date

Ähnlich wie bei Tagen können Sie auch Stunden, Minuten und Sekunden erhalten

period.getStandardHours();
period.getStandardMinutes();
period.getStandardSeconds();
2

Nachdem ich viele Antworten und Kommentare zu dieser Frage gelesen hatte, hatte ich den Eindruck, dass man entweder die Joda-Zeit verwenden muss oder einige Besonderheiten in Bezug auf die Sommerzeit usw. berücksichtigen muss Am Ende schrieb ich ein paar Zeilen Code, um die Differenz zwischen zwei Datumsangaben zu berechnen, ohne auf Datums- oder Zeitangaben bezogene Java-Klassen zu verwenden.

Im folgenden Code entsprechen die Zahlen von Jahr, Monat und Tag denen im realen Leben. Zum Beispiel am 24. Dezember 2015 ist das Jahr = 2015, der Monat = 12 und der Tag = 24.

Ich möchte diesen Code teilen, falls jemand anderes ihn verwenden möchte. Es gibt 3 Methoden: 1) Eine Methode, um herauszufinden, ob ein Jahr ein Schaltjahr ist. 2) Eine Methode zur Berechnung der Anzahl eines bestimmten Tages im Verhältnis zum 1. Januar eines bestimmten Jahres Tage zwischen zwei beliebigen Datumsangaben mit Methode 2 (Nummer des Enddatums minus Nummer des Startdatums).

Hier sind die Methoden:

1)

public static boolean isLeapYear (int year) {
    //Every 4. year is a leap year, except if the year is divisible by 100 and not by 400
    //For example 1900 is not a leap year but 2000 is

    boolean result = false;

    if (year % 4 == 0) {
        result = true;
    }
    if (year % 100 == 0) {
        result = false;
    }
    if (year % 400 == 0) {
        result = true;
    }

    return result;

}

2)

public static int daysGoneSince (int yearZero, int year, int month, int day) {
    //Calculates the day number of the given date; day 1 = January 1st in the yearZero

    //Validate the input
    if (year < yearZero || month < 1 || month > 12 || day < 1 || day > 31) {
        //Throw an exception
        throw new IllegalArgumentException("Too many or too few days in month or months in year or the year is smaller than year zero");
    }
    else if (month == 4 || month == 6 || month == 9 || month == 11) {//Months with 30 days
        if (day == 31) {
            //Throw an exception
            throw new IllegalArgumentException("Too many days in month");
        }
    }
    else if (month == 2) {//February 28 or 29
        if (isLeapYear(year)) {
            if (day > 29) {
                //Throw an exception
                throw new IllegalArgumentException("Too many days in month");
            }
        }
        else if (day > 28) {
            //Throw an exception
            throw new IllegalArgumentException("Too many days in month");
        }
    }

    //Start counting days
    int days = 0;

    //Days in the target month until the target day
    days = days + day;

    //Days in the earlier months in the target year
    for (int i = 1; i < month; i++) {
        switch (i) {
            case 1: case 3: case 5:
            case 7: case 8: case 10:
            case 12:
                days = days + 31;
                break;
            case 2:
                days = days + 28;
                if (isLeapYear(year)) {
                    days = days + 1;
                }
                break;
            case 4: case 6: case 9: case 11:
                days = days + 30;
                break;
        }
    }

    //Days in the earlier years
    for (int i = yearZero; i < year; i++) {
        days = days + 365;
        if (isLeapYear(i)) {
            days = days + 1;
        }
    }

    return days;

}

3)

public static int dateDiff (int startYear, int startMonth, int startDay, int endYear, int endMonth, int endDay) {

    int yearZero;

    //daysGoneSince presupposes that the first argument be smaller or equal to the second argument
    if (10000 * startYear + 100 * startMonth + startDay > 10000 * endYear + 100 * endMonth + endDay) {//If the end date is earlier than the start date
        yearZero = endYear;
    }
    else {
        yearZero = startYear;
    }

    return daysGoneSince(yearZero, endYear, endMonth, endDay) - daysGoneSince(yearZero, startYear, startMonth, startDay);

}
1

Frühere Versionen von Java können Sie ausprobieren.

 public static String daysBetween(Date createdDate, Date expiryDate) {

        Calendar createdDateCal = Calendar.getInstance();
        createdDateCal.clear();
        createdDateCal.setTime(createdDate);

        Calendar expiryDateCal = Calendar.getInstance();
        expiryDateCal.clear();
        expiryDateCal.setTime(expiryDate);


        long daysBetween = 0;
        while (createdDateCal.before(expiryDateCal)) {
            createdDateCal.add(Calendar.DAY_OF_MONTH, 1);
            daysBetween++;
        }
        return daysBetween+"";
    }
1
Kumar Abhishek

Da Sie Scala verwenden, gibt es eine sehr gute Scala-Bibliothek Lamma . Mit Lamma können Sie das Datum direkt mit dem --Operator reduzieren

scala> Date(2015, 5, 5) - 2     // minus days by int
res1: io.lamma.Date = Date(2015,5,3)

scala> Date(2015, 5, 15) - Date(2015, 5, 8)   // minus two days => difference between two days
res2: Int = 7
1
Max

versuche dies: 

int Epoch = (int) (new Java.text.SimpleDateFormat("MM/dd/yyyy HH:mm:ss").parse("01/01/1970  00:00:00").getTime() / 1000);

sie können den String in den parse () -Methoden param bearbeiten.

1
sabbibJAVA

Verwenden Sie einfach die untenstehende Methode mit zwei Date-Objekten. Wenn Sie das aktuelle Datum übergeben möchten, übergeben Sie einfach new Date() als zweiten Parameter, da es mit der aktuellen Uhrzeit initialisiert wird.

public String getDateDiffString(Date dateOne, Date dateTwo)
{
    long timeOne = dateOne.getTime();
    long timeTwo = dateTwo.getTime();
    long oneDay = 1000 * 60 * 60 * 24;
    long delta = (timeTwo - timeOne) / oneDay;

    if (delta > 0) {
        return "dateTwo is " + delta + " days after dateOne";
    }
    else {
        delta *= -1;
        return "dateTwo is " + delta + " days before dateOne";
     }
}

Abgesehen von der Anzahl der Tage, wenn Sie auch andere Parameterunterschiede verwenden möchten, verwenden Sie den folgenden Ausschnitt,

int year = delta / 365;
int rest = delta % 365;
int month = rest / 30;
rest = rest % 30;
int weeks = rest / 7;
int days = rest % 7;

P.S-Code wird vollständig aus einer Antwort SO übernommen.

1
Shubham A.

Es gibt einen einfachen Weg, dies in Java zu tun

// eine Utility-Methode erstellen

public long getDaysBetweenDates(Date d1, Date d2){
return TimeUnit.MILLISECONDS.toDays(d1.getTime() - d2.getTime());
}

Diese Methode gibt die Anzahl der Tage zwischen den zwei Datumsangaben zurück. Sie können entweder das Standard-Java-Datumsformat verwenden oder das Datumsformat problemlos konvertieren.

0
Vishal Kumar

Das Folgende ist eine Lösung, da es zahlreiche Möglichkeiten gibt, dies zu erreichen:

  import Java.util.*; 
   int syear = 2000;
   int eyear = 2000;
   int smonth = 2;//Feb
   int emonth = 3;//Mar
   int sday = 27;
   int eday = 1;
   Date startDate = new Date(syear-1900,smonth-1,sday);
   Date endDate = new Date(eyear-1900,emonth-1,eday);
   int difInDays = (int) ((endDate.getTime() - startDate.getTime())/(1000*60*60*24));
0
kundan bora

Dies ist ein weiteres Beispiel. Was grundsätzlich für benutzerdefinierte Muster funktioniert.

   public static LinkedHashMap<String, Object> checkDateDiff(DateTimeFormatter dtfObj, String startDate, String endDate)
   {
          Map<String, Object> dateDiffMap = new HashMap<String, Object>();
          DateTime start = DateTime.parse(startDate,dtfObj);
          DateTime end = DateTime.parse(endDate,dtfObj);
          Interval interval = new Interval(start, end);
          Period period = interval.toPeriod();

          dateDiffMap.put("ISO-8601_PERIOD_FORMAT", period);
          dateDiffMap.put("YEAR", period.getYears());
          dateDiffMap.put("MONTH", period.getMonths());
          dateDiffMap.put("WEEK", period.getWeeks());
          dateDiffMap.put("DAY", period.getWeeks());             
          dateDiffMap.put("HOUR", period.getHours());
          dateDiffMap.put("MINUTE", period.getMinutes());
          dateDiffMap.put("SECOND", period.getSeconds());

          return dateDiffMap;        
   }
0
The N..

Der TimeUnit-basierte Ansatz hat mir gefallen, bis ich herausfand, dass er nur die trivialen Fälle abdeckt, in denen die Anzahl der Einheiten einer Zeiteinheit in der nächsthöheren Einheit festgelegt ist. Dies bricht auseinander, wenn Sie wissen möchten, wie viele Monate, Jahre usw. dazwischen liegen. 

hier ist ein Zählverfahren, das nicht so effizient ist wie andere, aber es scheint für mich zu funktionieren und berücksichtigt auch die Sommerzeit.

public static String getOffsetAsString( Calendar cNow, Calendar cThen) {
    Calendar cBefore;
    Calendar cAfter;
    if ( cNow.getTimeInMillis() < cThen.getTimeInMillis()) {
        cBefore = ( Calendar) cNow.clone();
        cAfter = cThen;
    } else {
        cBefore = ( Calendar) cThen.clone();
        cAfter = cNow;
    }
    // compute diff
    Map<Integer, Long> diffMap = new HashMap<Integer, Long>();
    int[] calFields = { Calendar.YEAR, Calendar.MONTH, Calendar.DAY_OF_MONTH, Calendar.HOUR_OF_DAY, Calendar.MINUTE, Calendar.SECOND, Calendar.MILLISECOND};
    for ( int i = 0; i < calFields.length; i++) {
        int field = calFields[ i];
        long    d = computeDist( cAfter, cBefore, field);
        diffMap.put( field, d);
    }
    final String result = String.format( "%dY %02dM %dT %02d:%02d:%02d.%03d",
            diffMap.get( Calendar.YEAR), diffMap.get( Calendar.MONTH), diffMap.get( Calendar.DAY_OF_MONTH), diffMap.get( Calendar.HOUR_OF_DAY), diffMap.get( Calendar.MINUTE), diffMap.get( Calendar.SECOND), diffMap.get( Calendar.MILLISECOND));
    return result;
}

private static int computeDist( Calendar cAfter, Calendar cBefore, int field) {
    cBefore.setLenient( true);
    System.out.print( "D " + new Date( cBefore.getTimeInMillis()) + " --- " + new Date( cAfter.getTimeInMillis()) + ": ");
    int count = 0;
    if ( cAfter.getTimeInMillis() > cBefore.getTimeInMillis()) {
        int fVal = cBefore.get( field);
        while ( cAfter.getTimeInMillis() >= cBefore.getTimeInMillis()) {
            count++;
            fVal = cBefore.get( field);
            cBefore.set( field, fVal + 1);
            System.out.print( count + "/"  + ( fVal + 1) + ": " + new Date( cBefore.getTimeInMillis()) + " ] ");
        }
        int result = count - 1;
        cBefore.set( field, fVal);
        System.out.println( "" + result + " at: " + field + " cb = " + new Date( cBefore.getTimeInMillis()));
        return result;
    }
    return 0;
}
0
Ralf H

Wenn Sie fix die Ausgabe für Datumsbereiche durchführen möchten, die Zeitgrenze überschreiten (z. B. ein Datum in der Sommerzeit und das andere in der Winterzeit), können Sie dies verwenden der Unterschied in Tagen:

public static long calculateDifferenceInDays(Date start, Date end, Locale locale) {
    Calendar cal = Calendar.getInstance(locale);

    cal.setTime(start);
    cal.set(Calendar.HOUR_OF_DAY, 0);
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND, 0);
    cal.set(Calendar.MILLISECOND, 0);
    long startTime = cal.getTimeInMillis();

    cal.setTime(end);
    cal.set(Calendar.HOUR_OF_DAY, 0);
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND, 0);
    cal.set(Calendar.MILLISECOND, 0);
    long endTime = cal.getTimeInMillis();

    // calculate the offset if one of the dates is in summer time and the other one in winter time
    TimeZone timezone = cal.getTimeZone();
    int offsetStart = timezone.getOffset(startTime);
    int offsetEnd = timezone.getOffset(endTime);
    int offset = offsetEnd - offsetStart;

    return TimeUnit.MILLISECONDS.toDays(endTime - startTime + offset);
}
0
Fabi
public static void main(String[] args) {

    String dateStart = "01/14/2012 09:29:58";
    String dateStop = "01/14/2012 10:31:48";

    SimpleDateFormat format = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");

    Date d1 = null;
    Date d2 = null;

    try {
        d1 = format.parse(dateStart);
        d2 = format.parse(dateStop);

        DateTime date11 = new DateTime(d1);
        DateTime date22 = new DateTime(d2);
        int days = Days.daysBetween(date11.withTimeAtStartOfDay(), date22.withTimeAtStartOfDay()).getDays();
        int hours = Hours.hoursBetween(date11, date22).getHours() % 24;
        int minutes = Minutes.minutesBetween(date11, date22).getMinutes() % 60;
        int seconds = Seconds.secondsBetween(date11, date22).getSeconds() % 60;
        if (hours > 0 || minutes > 0 || seconds > 0) {
            days = days + 1;
        }

        System.out.println(days);

    } catch (Exception e) {
        e.printStackTrace();
    }

}

Dies gibt auch den Datumsunterschied für denselben Tag an

0
spysr

Eine weitere reine Java-Variante:

public boolean isWithin30Days(Calendar queryCalendar) {

    // 1. Take the date you are checking, and roll it back N days
    Calendar queryCalMinus30Days = Calendar.getInstance();
    queryCalMinus30Days.setTime(queryCalendar.getTime());
    queryCalMinus30Days.add(Calendar.DATE, -30); // subtract 30 days from the calendar

    // 2. Get respective milliseconds for the two Calendars: now & queryCal minus N days 
    long nowL = Calendar.getInstance().getTimeInMillis();
    long queryCalMinus30DaysL = queryCalMinus30Days.getTimeInMillis();

    // 3. if nowL is still less than the queryCalMinus30DaysL, it means queryCalendar is more than 30 days into future
    boolean isWithin30Days = nowL >= queryCalMinus30DaysL;

    return isWithin30Days;
}

Dank des Startcodes hier: https://stackoverflow.com/a/30207726/2162226

0
Gene Bo

Die Antwort von @Michael Borgwardt funktioniert in Android nicht richtig. Rundungsfehler bestehen. Beispiel 19. bis 21. Mai sagt 1 Tag, weil es 1,99 bis 1 wirft. 

Fix

int diffInDays = (int)Math.round(( (newerDate.getTime() - olderDate.getTime()) 
                 / (1000 * 60 * 60 * 24) ))

Beachten Sie, dass dies mit UTC-Datumsangaben funktioniert. Wenn Sie sich lokale Datumsangaben ansehen, kann der Unterschied daher ein Tag sein. Um korrekt mit lokalen Datumsangaben zu arbeiten, ist aufgrund der Sommerzeit ein völlig anderer Ansatz erforderlich.

0