Android/Java - Date Difference in days

前端 未结 18 894
感动是毒
感动是毒 2020-11-22 14:17

I am getting the current date (in format 12/31/1999 i.e. mm/dd/yyyy) as using the below code:

Textview txtViewData;
txtViewDate.setText(\"Today is \" +
              


        
相关标签:
18条回答
  • 2020-11-22 14:35

    All of these solutions suffer from one of two problems. Either the solution isn't perfectly accurate due to rounding errors, leap days and seconds, etc. or you end up looping over the number of days in between your two unknown dates.

    This solution solves the first problem, and improves the second by a factor of roughly 365, better if you know what your max range is.

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

    If you need days between dates (uninclusive of the latter date), just get rid of the + 1 when you see endDay - startDay + 1.

    0 讨论(0)
  • 2020-11-22 14:35

    One another way:

    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);
        }
    
    0 讨论(0)
  • 2020-11-22 14:38
            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 讨论(0)
  • 2020-11-22 14:39

    There's a simple solution, that at least for me, is the only feasible solution.

    The problem is that all the answers I see being tossed around - using Joda, or Calendar, or Date, or whatever - only take the amount of milliseconds into consideration. They end up counting the number of 24-hour cycles between two dates, rather than the actual number of days. So something from Jan 1st 11pm to Jan 2nd 1am will return 0 days.

    To count the actual number of days between startDate and endDate, simply do:

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

    This will return "1" between Jan 2nd and Jan 1st. If you need to count the end day, just add 1 to daysBetween (I needed to do that in my code since I wanted to count the total number of days in the range).

    This is somewhat similar to what Daniel has suggested but smaller code I suppose.

    0 讨论(0)
  • 2020-11-22 14:40

    Not really a reliable method, better of using 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
    

    Here's an approximation...

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

    To Parse the date from a string, you could use

      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....
    

    Although, since you're sure of the date format... You Could also do Integer.parseInt() on it's Substrings to obtain their numeric values.

    0 讨论(0)
  • 2020-11-22 14:40

    The Correct Way from Sam Quest's answer only works if the first date is earlier than the second. Moreover, it will return 1 if the two dates are within a single day.

    This is the solution that worked best for me. Just like most other solutions, it would still show incorrect results on two days in a year because of wrong day light saving offset.

    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);
    }
    
    0 讨论(0)
提交回复
热议问题