Domanda Come posso trovare il numero di anni tra due date?


Sto cercando di determinare un'età in anni a partire da una certa data. Qualcuno sa un modo pulito per farlo in Android? Ho a disposizione l'API Java, ovviamente, ma la java api è piuttosto debole, e speravo che Android avesse qualcosa che mi aiutasse.

EDIT: I molteplici consigli per utilizzare il tempo di Joda in Android mi preoccupa un po 'a causa di Android Java - La data di Joda è lenta e preoccupazioni correlate. Inoltre, la raccolta di una libreria non fornita con la piattaforma per qualcosa di queste dimensioni è probabilmente eccessiva.


44
2017-10-26 17:13


origine


risposte:


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;
}

84
2018-04-18 17:57



Consiglierei di usare il grande Joda-Time libreria per tutto ciò che riguarda la data in Java.

Per le tue esigenze puoi usare il Years.yearsBetween() metodo.


14
2017-10-26 17:27



tl; dr

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

java.time

Le vecchie classi di data e ora sono davvero pessime, tanto che sia Sun che Oracle hanno accettato di sostituirle con le classi java.time. Se si esegue un lavoro significativo con valori di data-ora, è utile aggiungere una libreria al progetto. La libreria Joda-Time ha avuto molto successo e raccomandato, ma ora è in modalità di manutenzione. Il team consiglia la migrazione alle classi java.time.

Gran parte della funzionalità java.time è back-porting su Java 6 e 7 in ThreeTen-Backport e ulteriormente adattato a androide in ThreeTenABP (vedere Come usare…).

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 );

Scarica alla console.

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

inizio: 2010-01-01 | stop: 2016-09-06 | anni: 6


5
2017-09-06 20:00



A quanto pare non posso ancora commentare, ma penso che tu possa semplicemente utilizzare il DAY_OF_YEAR per l'allenamento se dovresti aggiustare gli anni in basso (copiati e modificati dalla migliore risposta attuale)

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;
}

Allo stesso modo potresti probabilmente solo diffare le rappresentazioni ms del tempo e dividere per il numero di ms in un anno. Basta tenere tutto a lungo e questo dovrebbe essere abbastanza buono la maggior parte del tempo (bisestili, ahi) ma dipende dalla vostra applicazione per il numero di anni e da quanto performante quella funzione deve essere in grado di valere quel tipo di hack.


2
2017-10-09 17:30



Ecco quello che penso sia un metodo migliore:

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);
}

MODIFICARE

A parte un bug che ho risolto, questo metodo non funziona bene con gli anni bisestili. Ecco una suite di test completa. Immagino tu stia meglio usando la risposta accettata.

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);
        }
    }
}

2
2017-09-10 22:03



Se non vuoi calcolarlo usando il calendario di java puoi usare Androidi Time class  Dovrebbe essere più veloce ma non ho notato molta differenza quando sono passato.

Non sono riuscito a trovare alcuna funzione predefinita per determinare il tempo tra 2 date per un'età in Android. Ci sono alcune belle funzioni di supporto per ottenere il tempo formattato tra le date in DateUtils ma probabilmente non è quello che vuoi.


0
2017-10-26 17:59



So che hai chiesto una soluzione pulita, ma qui ci sono due sporche volte:

        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
2017-10-26 18:47



Prova questo:

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
2017-12-15 10:00