web-dev-qa-db-fra.com

Android/Java - Date Différence en jours

Je reçois la date actuelle (au format 12/31/1999 c'est-à-dire mm/jj/aaaa) en utilisant le code ci-dessous:

Textview txtViewData;
txtViewDate.setText("Today is " +
        Android.text.format.DateFormat.getDateFormat(this).format(new Date()));

et j’ai une autre date sous le format: 2010-08-25 (c’est-à-dire aaaa/mm/jj),

donc je veux trouver la différence entre la date en nombre de jours, comment puis-je trouver la différence en jours? 

(En d'autres termes, je veux trouver la différence entre DATE ACTUELLE - aaaa/mm/jj date formatée )

73
Paresh Mayani

Pas vraiment une méthode fiable, mieux d'utiliser JodaTime

  Calendar thatDay = Calendar.getInstance();
  thatDay.set(Calendar.DAY_OF_MONTH,25);
  thatDay.set(Calendar.MONTH,7); // 0-11 so 1 less
  thatDay.set(Calendar.YEAR, 1985);

  Calendar today = Calendar.getInstance();

  long diff = today.getTimeInMillis() - thatDay.getTimeInMillis(); //result in millis

Voici une approximation ...

long days = diff / (24 * 60 * 60 * 1000);

Pour analyser la date d'une chaîne, vous pouvez utiliser

  String strThatDay = "1985/08/25";
  SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd");
  Date d = null;
  try {
   d = formatter.parse(strThatDay);//catch exception
  } catch (ParseException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } 


  Calendar thatDay = Calendar.getInstance();
  thatDay.setTime(d); //rest is the same....

Cependant, puisque vous êtes sûr du format de date, vous pouvez également utiliser Integer.parseInt() sur ses sous-chaînes pour obtenir leurs valeurs numériques.

123
st0le

Ce n'est pas mon travail, a trouvé la réponse ici . ne voulait pas un lien brisé à l'avenir :).

La clé est cette ligne pour prendre en compte le réglage de lumière du jour, réf Full Code.

TimeZone.setDefault(TimeZone.getTimeZone("Europe/London"));

ou essayez de passer TimeZone en tant que paramètre à daysBetween() et appelez setTimeZone() dans les objets sDate et eDate.

Alors voilà:

public static Calendar getDatePart(Date date){
    Calendar cal = Calendar.getInstance();       // get calendar instance
    cal.setTime(date);      
    cal.set(Calendar.HOUR_OF_DAY, 0);            // set hour to midnight
    cal.set(Calendar.MINUTE, 0);                 // set minute in hour
    cal.set(Calendar.SECOND, 0);                 // set second in minute
    cal.set(Calendar.MILLISECOND, 0);            // set millisecond in second

    return cal;                                  // return the date part
}

getDatePart () extrait de ici

/**
 * This method also assumes endDate >= startDate
**/
public static long daysBetween(Date startDate, Date endDate) {
  Calendar sDate = getDatePart(startDate);
  Calendar eDate = getDatePart(endDate);

  long daysBetween = 0;
  while (sDate.before(eDate)) {
      sDate.add(Calendar.DAY_OF_MONTH, 1);
      daysBetween++;
  }
  return daysBetween;
}

Les nuances: Trouver la différence entre deux dates n'est pas aussi simple que de soustraire les deux dates et de diviser le résultat par (24 * 60 * 60 * 1000). Enfait, c'est erroné!

Par exemple: La différence entre les deux dates du 24/03/2007 et du 25/03/2007 devrait être de 1 jour; Cependant, en utilisant la méthode ci-dessus, au Royaume-Uni, vous aurez 0 jour! 

Voyez vous-même (code ci-dessous). Si vous optez pour le mode millisecondes, les erreurs seront arrondies et elles deviendront plus évidentes une fois que vous aurez une petite chose comme l'heure avancée entrer en scène.

Code complet:

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

public class DateTest {

public class DateTest {

static SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy");

public static void main(String[] args) {

  TimeZone.setDefault(TimeZone.getTimeZone("Europe/London"));

  //diff between these 2 dates should be 1
  Date d1 = new Date("01/01/2007 12:00:00");
  Date d2 = new Date("01/02/2007 12:00:00");

  //diff between these 2 dates should be 1
  Date d3 = new Date("03/24/2007 12:00:00");
  Date d4 = new Date("03/25/2007 12:00:00");

  Calendar cal1 = Calendar.getInstance();cal1.setTime(d1);
  Calendar cal2 = Calendar.getInstance();cal2.setTime(d2);
  Calendar cal3 = Calendar.getInstance();cal3.setTime(d3);
  Calendar cal4 = Calendar.getInstance();cal4.setTime(d4);

  printOutput("Manual   ", d1, d2, calculateDays(d1, d2));
  printOutput("Calendar ", d1, d2, daysBetween(cal1, cal2));
  System.out.println("---");
  printOutput("Manual   ", d3, d4, calculateDays(d3, d4));
  printOutput("Calendar ", d3, d4, daysBetween(cal3, cal4));
}


private static void printOutput(String type, Date d1, Date d2, long result) {
  System.out.println(type+ "- Days between: " + sdf.format(d1)
                    + " and " + sdf.format(d2) + " is: " + result);
}

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

/** Using Calendar - THE CORRECT WAY**/
public static long daysBetween(Date startDate, Date endDate) {
  ...
}

OUTPUT:

Manuel - Les jours compris entre le 1er janvier 2007 et le 2 janvier 2007 sont les suivants: 1

Calendrier - Jours entre: 01-Jan-2007 et 02-Jan-2007 est: 1


Manuel - Jours compris entre le 24 mars 2007 et le 25 mars 2007 soit: 0

Calendrier - Jours entre: 24 mars 2007 et 25 mars 2007 est: 1

78
Samuel

La plupart des réponses étaient bonnes et adaptées à votre problème de 

donc je veux trouver la différence entre la date en nombre de jours, comment puis-je trouver la différence en jours?

Je suggère cette approche très simple et directe qui garantit de vous donner la différence correcte dans n'importe quel fuseau horaire:

int difference= 
((int)((startDate.getTime()/(24*60*60*1000))
-(int)(endDate.getTime()/(24*60*60*1000))));

Et c'est tout!

36
Lisa Anne

Utiliser l'API jodatime

Days.daysBetween(start.toDateMidnight() , end.toDateMidnight() ).getDays() 

où 'début' et 'fin' sont vos objets DateTime . Pour analyser vos chaînes de date dans les objets DateTime, utilisez la méthode parseDateTime

Il existe également une bibliothèque JodaTime spécifique à Android .

23
Jeroen Rosenberg

Ce fragment représente l'heure d'été et est O (1).

private final static long MILLISECS_PER_DAY = 24 * 60 * 60 * 1000;

private static long getDateToLong(Date date) {
    return Date.UTC(date.getYear(), date.getMonth(), date.getDate(), 0, 0, 0);
}

public static int getSignedDiffInDays(Date beginDate, Date endDate) {
    long beginMS = getDateToLong(beginDate);
    long endMS = getDateToLong(endDate);
    long diff = (endMS - beginMS) / (MILLISECS_PER_DAY);
    return (int)diff;
}

public static int getUnsignedDiffInDays(Date beginDate, Date endDate) {
    return Math.abs(getSignedDiffInDays(beginDate, endDate));
}
14
markshiz

Ceci est simple et le meilleur calcul pour moi et peut être pour vous. 

       try {
            /// String CurrDate=  "10/6/2013";
            /// String PrvvDate=  "10/7/2013";
            Date date1 = null;
            Date date2 = null;
            SimpleDateFormat df = new SimpleDateFormat("M/dd/yyyy");
            date1 = df.parse(CurrDate);
            date2 = df.parse(PrvvDate);
            long diff = Math.abs(date1.getTime() - date2.getTime());
            long diffDays = diff / (24 * 60 * 60 * 1000);


            System.out.println(diffDays);

        } catch (Exception e1) {
            System.out.println("exception " + e1);
        }
6
Rishi Gautam

meilleure et la plus simple façon de le faire

  public int getDays(String begin) throws ParseException {
     long MILLIS_PER_DAY = 24 * 60 * 60 * 1000;
     SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy", Locale.ENGLISH);

    long begin = dateFormat.parse(begin).getTime();
    long end = new Date().getTime(); // 2nd date want to compare
    long diff = (end - begin) / (MILLIS_PER_DAY);
    return (int) diff;
}
3
Sumit

Le Correct Way de la réponse de Sam Quest ne fonctionne que si la première date est antérieure à la seconde. De plus, il retournera 1 si les deux dates sont dans la même journée.

C'est la solution qui a le mieux fonctionné pour moi. Comme pour la plupart des autres solutions, des résultats incorrects sont affichés deux jours par an en raison d'un décalage erroné de l'heure.

private final static long MILLISECS_PER_DAY = 24 * 60 * 60 * 1000;

long calculateDeltaInDays(Calendar a, Calendar b) {

    // Optional: avoid cloning objects if it is the same day
    if(a.get(Calendar.ERA) == b.get(Calendar.ERA) 
            && a.get(Calendar.YEAR) == b.get(Calendar.YEAR)
            && a.get(Calendar.DAY_OF_YEAR) == b.get(Calendar.DAY_OF_YEAR)) {
        return 0;
    }
    Calendar a2 = (Calendar) a.clone();
    Calendar b2 = (Calendar) b.clone();
    a2.set(Calendar.HOUR_OF_DAY, 0);
    a2.set(Calendar.MINUTE, 0);
    a2.set(Calendar.SECOND, 0);
    a2.set(Calendar.MILLISECOND, 0);
    b2.set(Calendar.HOUR_OF_DAY, 0);
    b2.set(Calendar.MINUTE, 0);
    b2.set(Calendar.SECOND, 0);
    b2.set(Calendar.MILLISECOND, 0);
    long diff = a2.getTimeInMillis() - b2.getTimeInMillis();
    long days = diff / MILLISECS_PER_DAY;
    return Math.abs(days);
}
3
ccpizza

Toutes ces solutions souffrent d'un des deux problèmes. Soit la solution n'est pas parfaitement précise en raison d'erreurs d'arrondi, de jours bissextiles, de secondes, etc. Vous pouvez vous retrouver en boucle sur le nombre de jours entre vos deux dates inconnues.

Cette solution résout le premier problème et améliore le second d'un facteur d'environ 365, mieux si vous connaissez votre plage maximale.

/**
 * @param thisDate
 * @param thatDate
 * @param maxDays
 *            set to -1 to not set a max
 * @returns number of days covered between thisDate and thatDate, inclusive, i.e., counting both
 *          thisDate and thatDate as an entire day. Will short out if the number of days exceeds
 *          or meets maxDays
 */
public static int daysCoveredByDates(Date thisDate, Date thatDate, int maxDays) {
    //Check inputs
    if (thisDate == null || thatDate == null) {
        return -1;
    }

    //Set calendar objects
    Calendar startCal = Calendar.getInstance();
    Calendar endCal = Calendar.getInstance();
    if (thisDate.before(thatDate)) {
        startCal.setTime(thisDate);
        endCal.setTime(thatDate);
    }
    else {
        startCal.setTime(thatDate);
        endCal.setTime(thisDate);
    }

    //Get years and dates of our times.
    int startYear = startCal.get(Calendar.YEAR);
    int endYear = endCal.get(Calendar.YEAR);
    int startDay = startCal.get(Calendar.DAY_OF_YEAR);
    int endDay = endCal.get(Calendar.DAY_OF_YEAR);

    //Calculate the number of days between dates.  Add up each year going by until we catch up to endDate.
    while (startYear < endYear && maxDays >= 0 && endDay - startDay + 1 < maxDays) {
        endDay += startCal.getActualMaximum(Calendar.DAY_OF_YEAR); //adds the number of days in the year startDate is currently in
        ++startYear;
        startCal.set(Calendar.YEAR, startYear); //reup the year
    }
    int days = endDay - startDay + 1;

    //Honor the maximum, if set
    if (maxDays >= 0) {
        days = Math.min(days, maxDays);
    }
    return days;
}

Si vous avez besoin de jours entre les dates (non incluses dans cette dernière date), supprimez simplement le + 1 lorsque vous voyez endDay - startDay + 1.

2
drdaanger

Utilisez les fonctions suivantes:

   /**
     * Returns the number of days between two dates. The time part of the
     * days is ignored in this calculation, so 2007-01-01 13:00 and 2007-01-02 05:00
     * have one day inbetween.
     */
    public static long daysBetween(Date firstDate, Date secondDate) {
        // We only use the date part of the given dates
        long firstSeconds = truncateToDate(firstDate).getTime()/1000;
        long secondSeconds = truncateToDate(secondDate).getTime()/1000;
        // Just taking the difference of the millis.
        // These will not be exactly multiples of 24*60*60, since there
        // might be daylight saving time somewhere inbetween. However, we can
        // say that by adding a half day and rounding down afterwards, we always
        // get the full days.
        long difference = secondSeconds-firstSeconds;
        // Adding half a day
        if( difference >= 0 ) {
            difference += SECONDS_PER_DAY/2; // plus half a day in seconds
        } else {
            difference -= SECONDS_PER_DAY/2; // minus half a day in seconds
        }
        // Rounding down to days
        difference /= SECONDS_PER_DAY;

        return difference;
    }

    /**
     * Truncates a date to the date part alone.
     */
    @SuppressWarnings("deprecation")
    public static Date truncateToDate(Date d) {
        if( d instanceof Java.sql.Date ) {
            return d; // Java.sql.Date is already truncated to date. And raises an
                      // Exception if we try to set hours, minutes or seconds.
        }
        d = (Date)d.clone();
        d.setHours(0);
        d.setMinutes(0);
        d.setSeconds(0);
        d.setTime(((d.getTime()/1000)*1000));
        return d;
    }
2
Daniel

Il existe une solution simple, du moins pour moi, est la seule solution réalisable.

Le problème est que toutes les réponses que je vois être mélangées - en utilisant Joda, ou Calendrier, ou Date, ou peu importe - ne tiennent compte que de la quantité de millisecondes. Ils finissent par compter le nombre de cycles de 24 heures entre deux dates, plutôt que le nombre réel de jours. Donc, quelque chose du 1er janvier 23h00 au 2 janvier 1h00 retournera 0 jours.

Pour compter le nombre réel de jours entre startDate et endDate, faites simplement:

// Find the sequential day from a date, essentially resetting time to start of the day
long startDay = startDate.getTime() / 1000 / 60 / 60 / 24;
long endDay = endDate.getTime() / 1000 / 60 / 60 / 24;

// Find the difference, duh
long daysBetween = endDay - startDay;

Cela retournera "1" entre le 2 et le 1er janvier. Si vous devez compter le jour de fin, ajoutez simplement 1 à daysBetween (je devais le faire dans mon code car je voulais compter le nombre total de jours de la plage).

Ceci est un peu similaire à ce que Daniel a suggéré mais un code plus petit je suppose.

2
zeh

Un autre moyen:

public static int numberOfDaysBetweenDates(Calendar fromDay, Calendar toDay) {
        fromDay = calendarStartOfDay(fromDay);
        toDay = calendarStartOfDay(toDay);
        long from = fromDay.getTimeInMillis();
        long to = toDay.getTimeInMillis();
        return (int) TimeUnit.MILLISECONDS.toDays(to - from);
    }
1
anil

J'ai trouvé un moyen très simple de faire cela et c'est ce que j'utilise dans mon application.

Disons que vous avez les dates dans les objets Time (ou autre chose, nous avons juste besoin des millisecondes):

Time date1 = initializeDate1(); //get the date from somewhere
Time date2 = initializeDate2(); //get the date from somewhere

long millis1 = date1.toMillis(true);
long millis2 = date2.toMillis(true);

long difference = millis2 - millis1 ;

//now get the days from the difference and that's it
long days = TimeUnit.MILLISECONDS.toDays(difference);

//now you can do something like
if(days == 7)
{
    //do whatever when there's a week of difference
}

if(days >= 30)
{
    //do whatever when it's been a month or more
}
0
Gonan
        Date userDob = new SimpleDateFormat("yyyy-MM-dd").parse(dob);
        Date today = new Date();
        long diff =  today.getTime() - userDob.getTime();
        int numOfDays = (int) (diff / (1000 * 60 * 60 * 24));
        int hours = (int) (diff / (1000 * 60 * 60));
        int minutes = (int) (diff / (1000 * 60));
        int seconds = (int) (diff / (1000));
0
Nilesh Savaliya

Joda-Time

Le meilleur moyen consiste à utiliser Joda-Time , la bibliothèque à code source ouverte très performante à ajouter à votre projet. 

String date1 = "2015-11-11";
String date2 = "2013-11-11";
DateTimeFormatter formatter = new DateTimeFormat.forPattern("yyyy-MM-dd");
DateTime d1 = formatter.parseDateTime(date1);
DateTime d2 = formatter.parseDateTime(date2);
long diffInMillis = d2.getMillis() - d1.getMillis();

Duration duration = new Duration(d1, d2);
int days = duration.getStandardDays();
int hours = duration.getStandardHours();
int minutes = duration.getStandardMinutes();

Si vous utilisez Android Studio , il est très facile d’ajouter joda-time. Dans votre build.gradle (app): 

dependencies {
  compile 'joda-time:joda-time:2.4'
  compile 'joda-time:joda-time:2.4'
  compile 'joda-time:joda-time:2.2'
}
0
Kristy Welsh
        public void dateDifferenceExample() {

        // Set the date for both of the calendar instance
        GregorianCalendar calDate = new GregorianCalendar(2012, 10, 02,5,23,43);
        GregorianCalendar cal2 = new GregorianCalendar(2015, 04, 02);

        // Get the represented date in milliseconds
        long millis1 = calDate.getTimeInMillis();
        long millis2 = cal2.getTimeInMillis();

        // Calculate difference in milliseconds
        long diff = millis2 - millis1;

        // Calculate difference in seconds
        long diffSeconds = diff / 1000;

        // Calculate difference in minutes
        long diffMinutes = diff / (60 * 1000);

        // Calculate difference in hours
        long diffHours = diff / (60 * 60 * 1000);

        // Calculate difference in days
        long diffDays = diff / (24 * 60 * 60 * 1000);
    Toast.makeText(getContext(), ""+diffSeconds, Toast.LENGTH_SHORT).show();


}
0
Syed Danish Haider

utiliser ces fonctions

    public static int getDateDifference(int previousYear, int previousMonthOfYear, int previousDayOfMonth, int nextYear, int nextMonthOfYear, int nextDayOfMonth, int differenceToCount){
    // int differenceToCount = can be any of the following
    //  Calendar.MILLISECOND;
    //  Calendar.SECOND;
    //  Calendar.MINUTE;
    //  Calendar.HOUR;
    //  Calendar.DAY_OF_MONTH;
    //  Calendar.MONTH;
    //  Calendar.YEAR;
    //  Calendar.----

    Calendar previousDate = Calendar.getInstance();
    previousDate.set(Calendar.DAY_OF_MONTH, previousDayOfMonth);
    // month is zero indexed so month should be minus 1
    previousDate.set(Calendar.MONTH, previousMonthOfYear);
    previousDate.set(Calendar.YEAR, previousYear);

    Calendar nextDate = Calendar.getInstance();
    nextDate.set(Calendar.DAY_OF_MONTH, previousDayOfMonth);
    // month is zero indexed so month should be minus 1
    nextDate.set(Calendar.MONTH, previousMonthOfYear);
    nextDate.set(Calendar.YEAR, previousYear);

    return getDateDifference(previousDate,nextDate,differenceToCount);
}
public static int getDateDifference(Calendar previousDate,Calendar nextDate,int differenceToCount){
    // int differenceToCount = can be any of the following
    //  Calendar.MILLISECOND;
    //  Calendar.SECOND;
    //  Calendar.MINUTE;
    //  Calendar.HOUR;
    //  Calendar.DAY_OF_MONTH;
    //  Calendar.MONTH;
    //  Calendar.YEAR;
    //  Calendar.----

    //raise an exception if previous is greater than nextdate.
    if(previousDate.compareTo(nextDate)>0){
        throw new RuntimeException("Previous Date is later than Nextdate");
    }

    int difference=0;
    while(previousDate.compareTo(nextDate)<=0){
        difference++;
        previousDate.add(differenceToCount,1);
    }
    return difference;
}
0
neal zedlav