web-dev-qa-db-de.com

Wie kann ich die Anzahl der Jahre zwischen zwei Terminen ermitteln?

Ich versuche, ein Alter in Jahren ab einem bestimmten Datum festzulegen. Kennt jemand eine saubere Möglichkeit, dies in Android zu tun? Ich habe die Java-API offenbar zur Verfügung, aber die Java-API ist ziemlich schwach und ich hatte gehofft, dass Android mir etwas zu helfen hat.

BEARBEITEN: Die mehrfachen Empfehlungen zur Verwendung der Joda-Zeit in Android machen mir etwas Sorgen wegen Android Java - Joda Date ist langsam und verwandte Bedenken. Außerdem ist es wahrscheinlich übertrieben, eine Bibliothek einzuladen, die nicht im Lieferumfang der Plattform enthalten ist. 

48
Micah Hainline
import Java.util.Calendar;
import Java.util.Locale;
import static Java.util.Calendar.*;
import Java.util.Date;

public static int getDiffYears(Date first, Date last) {
    Calendar a = getCalendar(first);
    Calendar b = getCalendar(last);
    int diff = b.get(YEAR) - a.get(YEAR);
    if (a.get(MONTH) > b.get(MONTH) || 
        (a.get(MONTH) == b.get(MONTH) && a.get(DATE) > b.get(DATE))) {
        diff--;
    }
    return diff;
}

public static Calendar getCalendar(Date date) {
    Calendar cal = Calendar.getInstance(Locale.US);
    cal.setTime(date);
    return cal;
}
93
sinuhepop

Ich würde empfehlen, die große Joda-Time -Bibliothek für alles Datum in Java zu verwenden.

Für Ihre Bedürfnisse können Sie die Methode Years.yearsBetween() verwenden.

15
Marcelo

tl; dr

ChronoUnit.YEARS.between( 
    LocalDate.of( 2010 , 1 , 1 ) , 
    LocalDate.now( ZoneId.of( "America/Montreal" ) ) 
)

Java.time

Die alten Date-Time-Klassen sind wirklich schlecht, so schlecht, dass Sun und Oracle zugestimmt haben, sie durch die Java.time-Klassen zu ersetzen. Wenn Sie mit Datums- und Uhrzeitwerten überhaupt wichtige Arbeiten ausführen, lohnt es sich, Ihrem Projekt eine Bibliothek hinzuzufügen. Die Joda-Time-Bibliothek war sehr erfolgreich und wurde empfohlen, befindet sich jedoch jetzt im Wartungsmodus. Das Team empfiehlt die Migration zu den Java.time-Klassen.

Ein Großteil der Java.time-Funktionalität wird auf Java 6 & 7 in ThreeTen-Backport zurückportiert und weiter angepasst an Android in - ThreeTenABP (siehe How to use… ).

LocalDate start = LocalDate.of( 2010 , 1 , 1 ) ;
LocalDate stop = LocalDate.now( ZoneId.of( "America/Montreal" ) );
long years = Java.time.temporal.ChronoUnit.YEARS.between( start , stop );

Dump zur Konsole.

System.out.println( "start: " + start + " | stop: " + stop + " | years: " + years ) ;

beginn: 01.01.2010 | Halt: 06.09.2016 | Jahre: 6


About Java.time

Das Java.time Framework ist in Java 8 und höher. Diese Klassen ersetzen das lästige alte Legacy Datum-Zeit-Klassen wie Java.util.Date , Calendar , & SimpleDateFormat .

Das Joda-Time -Projekt, das sich jetzt im Wartungsmodus befindet, rät zur Migration in die Java.time -Klassen.

Weitere Informationen finden Sie im Oracle Tutorial . Durchsuchen Sie Stack Overflow nach vielen Beispielen und Erklärungen. Spezifikation ist JSR 31 .

Sie können Java.time Objekte direkt mit Ihrer Datenbank austauschen. Verwenden Sie einen JDBC-Treiber , der JDBC 4.2 oder höher entspricht. Keine Notwendigkeit für Zeichenfolgen, keine Notwendigkeit für Java.sql.* Klassen.

Woher bekommen Sie die Java.time-Klassen?

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

13
Basil Bourque

Ich kann es anscheinend noch nicht kommentieren, aber ich denke, Sie können einfach mit DAY_OF_YEAR trainieren, wenn Sie die Jahre ein wenig anpassen sollten (kopiert und modifiziert von der aktuellen besten Antwort).

public static int getDiffYears(Date first, Date last) {
    Calendar a = getCalendar(first);
    Calendar b = getCalendar(last);
    int diff = b.get(Calendar.YEAR) - a.get(Calendar.YEAR);
    if (a.get(Calendar.DAY_OF_YEAR) > b.get(Calendar.DAY_OF_YEAR)) {
        diff--;
    }
    return diff;
}

public static Calendar getCalendar(Date date) {
    Calendar cal = Calendar.getInstance(Locale.US);
    cal.setTime(date);
    return cal;
}

In ähnlicher Weise könnten Sie die ms-Darstellungen der Zeit wahrscheinlich nur differenzieren und durch die Anzahl der ms in einem Jahr dividieren. Behalten Sie einfach alles bei, und das sollte die meiste Zeit gut genug sein (Schaltjahre, autsch), aber es hängt von Ihrer Anwendung für die Anzahl der Jahre ab und wie leistungsfähig diese Funktion sein muss, wenn es Wetter ist, wäre es diese Art von Hack wert.

2
sagechufi

Ich denke, das ist eine bessere Methode:

public int getYearsBetweenDates(Date first, Date second) {
    Calendar firstCal = GregorianCalendar.getInstance();
    Calendar secondCal = GregorianCalendar.getInstance();

    firstCal.setTime(first);
    secondCal.setTime(second);

    secondCal.add(Calendar.DAY_OF_YEAR, 1 - firstCal.get(Calendar.DAY_OF_YEAR));

    return secondCal.get(Calendar.YEAR) - firstCal.get(Calendar.YEAR);
}

EDIT

Abgesehen von einem Fehler, den ich behoben habe, funktioniert diese Methode nicht gut mit Schaltjahren. Hier ist eine komplette Testsuite. Ich denke, Sie sind besser dran mit der akzeptierten Antwort.

import Java.text.SimpleDateFormat;
import Java.util.Calendar;
import Java.util.Date;
import Java.util.GregorianCalendar;

class YearsBetweenDates {
    public static int getYearsBetweenDates(Date first, Date second) {
        Calendar firstCal = GregorianCalendar.getInstance();
        Calendar secondCal = GregorianCalendar.getInstance();

        firstCal.setTime(first);
        secondCal.setTime(second);

        secondCal.add(Calendar.DAY_OF_YEAR, 1 - firstCal.get(Calendar.DAY_OF_YEAR));

        return secondCal.get(Calendar.YEAR) - firstCal.get(Calendar.YEAR);
    }

    private static class TestCase {
        public Calendar date1;
        public Calendar date2;
        public int expectedYearDiff;
        public String comment;

        public TestCase(Calendar date1, Calendar date2, int expectedYearDiff, String comment) {
            this.date1 = date1;
            this.date2 = date2;
            this.expectedYearDiff = expectedYearDiff;
            this.comment = comment;
        }
    }

    private static TestCase[] tests = {
        new TestCase(
                new GregorianCalendar(2014, Calendar.JULY, 15),
                new GregorianCalendar(2015, Calendar.JULY, 15),
                1,
                "exactly one year"),
        new TestCase(
                new GregorianCalendar(2014, Calendar.JULY, 15),
                new GregorianCalendar(2017, Calendar.JULY, 14),
                2,
                "one day less than 3 years"),
        new TestCase(
                new GregorianCalendar(2015, Calendar.NOVEMBER, 3),
                new GregorianCalendar(2017, Calendar.MAY, 3),
                1,
                "a year and a half"),
        new TestCase(
                new GregorianCalendar(2016, Calendar.JULY, 15),
                new GregorianCalendar(2017, Calendar.JULY, 15),
                1,
                "leap years do not compare correctly"),
    };

    public static void main(String[] args) {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        for (TestCase t : tests) {
            int diff = getYearsBetweenDates(t.date1.getTime(), t.date2.getTime());
            String result = diff == t.expectedYearDiff ? "PASS" : "FAIL";
            System.out.println(t.comment + ": " +
                    df.format(t.date1.getTime()) + " -> " +
                    df.format(t.date2.getTime()) + " = " +
                    diff + ": " + result);
        }
    }
}
1
SnakE

Wenn Sie es nicht mit Javas Kalender berechnen möchten, können Sie Androids Time class verwenden. Es soll schneller sein, aber ich habe beim Wechsel nicht viel Unterschied bemerkt.

Ich konnte keine vordefinierten Funktionen finden, um die Zeit zwischen zwei Datumsangaben für ein Alter in Android zu bestimmen. Es gibt einige Nice-Hilfsfunktionen, um die formatierte Zeit zwischen den Datumsangaben in den DateUtils zu erhalten.

0
dweebo

Danke an @Ole V.v für die Überprüfung: Ich habe einige eingebaute Bibliotheksklassen gefunden, die dasselbe tun 

    int noOfMonths = 0;
    org.joda.time.format.DateTimeFormatter formatter = DateTimeFormat
            .forPattern("yyyy-MM-dd");
    DateTime dt = formatter.parseDateTime(startDate);

    DateTime endDate11 = new DateTime();
    Months m = Months.monthsBetween(dt, endDate11);
    noOfMonths = m.getMonths();
    System.out.println(noOfMonths);
0
keyRen
// int year =2000;  int month =9 ;    int day=30;

    public int getAge (int year, int month, int day) {

            GregorianCalendar cal = new GregorianCalendar();
            int y, m, d, noofyears;         

            y = cal.get(Calendar.YEAR);// current year ,
            m = cal.get(Calendar.MONTH);// current month 
            d = cal.get(Calendar.DAY_OF_MONTH);//current day
            cal.set(year, month, day);// here ur date 
            noofyears = y - cal.get(Calendar.YEAR);
            if ((m < cal.get(Calendar.MONTH))
                            || ((m == cal.get(Calendar.MONTH)) && (d < cal
                                            .get(Calendar.DAY_OF_MONTH)))) {
                    --noofyears;
            }
            if(noofyears < 0)
                    throw new IllegalArgumentException("age < 0");
             System.out.println(noofyears);
            return noofyears;
0
Rishi Gautam

Sie können einfach die Differenz zwischen zwei Datumsangaben in Millisekunden berechnen und durch Sekunden, Minuten, Stunden, Tage und Monat dividieren

versuche dies,

public int findDiff(Date fromDate, Date toDate) {

    if(fromDate == null || toDate == null) {
        return -1;
    }

    long diff = toDate.getTime() - fromDate.getTime();

    int diffInYears = (int) (diff / (60 * 60 * 1000 * 24 * 30.41666666 * 12));
    return diffInYears;
}
0
Thiru Maran

Ich weiß, du hast um eine saubere Lösung gebeten, aber hier sind zwei schmutzig:

        static void diffYears1()
{
    SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
    Calendar calendar1 = Calendar.getInstance(); // now
    String toDate = dateFormat.format(calendar1.getTime());

    Calendar calendar2 = Calendar.getInstance();
    calendar2.add(Calendar.DAY_OF_YEAR, -7000); // some date in the past
    String fromDate = dateFormat.format(calendar2.getTime());

    // just simply add one year at a time to the earlier date until it becomes later then the other one 
    int years = 0;
    while(true)
    {
        calendar2.add(Calendar.YEAR, 1);
        if(calendar2.getTimeInMillis() < calendar1.getTimeInMillis())
            years++;
        else
            break;
    }

    System.out.println(years + " years between " + fromDate + " and " + toDate);
}

static void diffYears2()
{
    SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
    Calendar calendar1 = Calendar.getInstance(); // now
    String toDate = dateFormat.format(calendar1.getTime());

    Calendar calendar2 = Calendar.getInstance();
    calendar2.add(Calendar.DAY_OF_YEAR, -7000); // some date in the past
    String fromDate = dateFormat.format(calendar2.getTime());

    // first get the years difference from the dates themselves
    int years = calendar1.get(Calendar.YEAR) - calendar2.get(Calendar.YEAR);
    // now make the earlier date the same year as the later
    calendar2.set(Calendar.YEAR, calendar1.get(Calendar.YEAR));
    // and see if new date become later, if so then one year was not whole, so subtract 1 
    if(calendar2.getTimeInMillis() > calendar1.getTimeInMillis())
        years--;

    System.out.println(years + " years between " + fromDate + " and " + toDate);
}
0
Ma99uS

Versuche dies:

int getYear(Date date1,Date date2){ 
      SimpleDateFormat simpleDateformat=new SimpleDateFormat("yyyy");
      Integer.parseInt(simpleDateformat.format(date1));

      return Integer.parseInt(simpleDateformat.format(date2))- Integer.parseInt(simpleDateformat.format(date1));

    }
0
abobjects.com

Dies wird funktionieren und wenn Sie möchten, dass die Anzahl der Jahre 12 zu 1 ersetzt 

    String date1 = "07-01-2015";
    String date2 = "07-11-2015";
    int i = Integer.parseInt(date1.substring(6));
    int j = Integer.parseInt(date2.substring(6));
    int p = Integer.parseInt(date1.substring(3,5));
    int q = Integer.parseInt(date2.substring(3,5));


    int z;
    if(q>=p){
        z=q-p + (j-i)*12;
    }else{
        z=p-q + (j-i)*12;
    }
    System.out.println("The Total Months difference between two dates is --> "+z+" Months");
0
keyRen