Ява, рассчитать количество дней между двумя датами [дубликат]


этот вопрос уже есть ответ здесь:

Возможные Дубликаты:
вычисление разницы между двумя экземплярами даты Java

в Java, я хочу вычислить количество дней между двумя датами.

в моей базе они хранятся как DATE тип данных, но в моем коде они являются строками.

Я хочу, чтобы вычислить количество дней между этими двумя строками.

10 54

10 ответов:

Ну для начала, вы должны только иметь дело с ними как строки, когда вы должны. Большую часть времени вы должны работать с ними в тип данных, который фактически описывает данные, с которыми вы работаете.

Я бы рекомендовал вам использовать Джода Времени, что намного лучше API, чем Date/Calendar. Похоже, вы должны использовать LocalDate тип в этом случае. Затем вы можете использовать:

int days = Days.daysBetween(date1, date2).getDays();

попробуйте этот код

     Calendar cal1 = new GregorianCalendar();
     Calendar cal2 = new GregorianCalendar();

     SimpleDateFormat sdf = new SimpleDateFormat("ddMMyyyy");

     Date date = sdf.parse("your first date");
     cal1.setTime(date)
     date = sdf.parse("your second date");
     cal2.setTime(date);

    //cal1.set(2008, 8, 1); 
     //cal2.set(2008, 9, 31);
     System.out.println("Days= "+daysBetween(cal1.getTime(),cal2.getTime()));

эта функция

     public int daysBetween(Date d1, Date d2){
             return (int)( (d2.getTime() - d1.getTime()) / (1000 * 60 * 60 * 24));
     }

В Java 8. Вы можете использовать экземпляры Enum ChronoUnit для расчета количества времени в различных единицах (дни, месяцы, секунды).

Например:

ChronoUnit.DAYS.between(startDate,endDate)

Я знаю, что этой теме уже два года, я все еще не вижу правильного ответа здесь.

если вы не хотите использовать Joda или иметь Java 8, и если вам нужно подорвать даты под влиянием летнего времени.

поэтому я написал свое собственное решение. Важным аспектом является то, что он работает только в том случае, если вы действительно заботитесь только о датах, потому что необходимо отбросить информацию о времени, поэтому, если вы хотите что-то вроде 25.06.2014 - 01.01.2010 = 1636, это должно работать независимо от ДСТ:

private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd.MM.yyyy");

public static long getDayCount(String start, String end) {
  long diff = -1;
  try {
    Date dateStart = simpleDateFormat.parse(start);
    Date dateEnd = simpleDateFormat.parse(end);

    //time is always 00:00:00 so rounding should help to ignore the missing hour when going from winter to summer time as well as the extra hour in the other direction
    diff = Math.round((dateEnd.getTime() - dateStart.getTime()) / (double) 86400000);
  } catch (Exception e) {
    //handle the exception according to your own situation
  }
  return diff;
}

как всегда 00:00:00, используя double, а затем Math.round() должно помочь игнорировать отсутствующие 60000ms (1 час) при переходе от зимнего к летнему времени, а также дополнительный час, если переход от лета к зиме.

это небольшой тест JUnit4 я использую, чтобы доказать это:

@Test
public void testGetDayCount() {
  String startDateStr = "01.01.2010";
  GregorianCalendar gc = new GregorianCalendar(locale);
  try {
    gc.setTime(simpleDateFormat.parse(startDateStr));
  } catch (Exception e) {
  }

  for (long i = 0; i < 10000; i++) {
    String dateStr = simpleDateFormat.format(gc.getTime());
    long dayCount = getDayCount(startDateStr, dateStr);
    assertEquals("dayCount must be equal to the loop index i: ", i, dayCount);
    gc.add(GregorianCalendar.DAY_OF_YEAR, 1);
  }
}

... или, если вы хотите увидеть, что делает "жизнь", замените утверждение просто:

System.out.println("i: " + i + " | " + dayCount + " - getDayCount(" + startDateStr + ", " + dateStr + ")");

... и это то, что выход должен выглядеть например:

  i: 0 | 0  - getDayCount(01.01.2010, 01.01.2010)
  i: 1 | 1  - getDayCount(01.01.2010, 02.01.2010)
  i: 2 | 2  - getDayCount(01.01.2010, 03.01.2010)
  i: 3 | 3  - getDayCount(01.01.2010, 04.01.2010)
  ...
  i: 1636 | 1636  - getDayCount(01.01.2010, 25.06.2014)
  ...
  i: 9997 | 9997  - getDayCount(01.01.2010, 16.05.2037)
  i: 9998 | 9998  - getDayCount(01.01.2010, 17.05.2037)
  i: 9999 | 9999  - getDayCount(01.01.2010, 18.05.2037)

вот небольшая программа, которая может помочь вам:

import java.util.*;

public class DateDifference {
    public static void main(String args[]){
        DateDifference difference = new DateDifference();
    }

    DateDifference() {
        Calendar cal1 = new GregorianCalendar();
        Calendar cal2 = new GregorianCalendar();

        cal1.set(2010, 12, 1); 
        cal2.set(2011, 9, 31);
        System.out.println("Days= "+daysBetween(cal1.getTime(),cal2.getTime()));
    }

    public int daysBetween(Date d1, Date d2) {
        return (int)( (d2.getTime() - d1.getTime()) / (1000 * 60 * 60 * 24));
    }
}
// http://en.wikipedia.org/wiki/Julian_day
public static int julianDay(int year, int month, int day) {
  int a = (14 - month) / 12;
  int y = year + 4800 - a;
  int m = month + 12 * a - 3;
  int jdn = day + (153 * m + 2)/5 + 365*y + y/4 - y/100 + y/400 - 32045;
  return jdn;
}

public static int diff(int y1, int m1, int d1, int y2, int m2, int d2) {
  return julianDay(y1, m1, d1) - julianDay(y2, m2, d2);
}

Я действительно действительно Новичок в Java, поэтому я уверен, что есть еще лучший способ сделать то, что я предлагаю.

у меня было такое же требование, и я сделал это, используя разницу между DAYOFYEAR двух дат. Это казалось более простым способом сделать это...

Я не могу реально оценить это решение с точки зрения производительности и стабильности, но я думаю, что это нормально.

здесь:

    public static void main(String[] args) throws ParseException {



//Made this part of the code just to create the variables i'll use.
//I'm in Brazil and the date format here is DD/MM/YYYY, but wont be an issue to you guys. 
//It will work anyway with your format.

    String s1 = "18/09/2014"; 
    String s2 = "01/01/2014";
    DateFormat f = DateFormat.getDateInstance();
    Date date1 = f.parse(s1); 
    Date date2 = f.parse(s2);




//Here's the part where we get the days between two dates.

    Calendar day1 = Calendar.getInstance();
    Calendar day2 = Calendar.getInstance(); 
    day1.setTime(date1);
    day2.setTime(date2);

    int daysBetween = day1.get(Calendar.DAY_OF_YEAR) - day2.get(Calendar.DAY_OF_YEAR);      




//Some code just to show the result...
    f = DateFormat.getDateInstance(DateFormat.MEDIUM);
    System.out.println("There's " + daysBetween + " days between " + f.format(day1.getTime()) + " and " + f.format(day2.getTime()) + ".");



    }

в этом случае выход будет (помня, что я использую Формат даты ДД / ММ / гггг):

There's 260 days between 18/09/2014 and 01/01/2014.

эта функция хороша для меня:

public static int getDaysCount(Date begin, Date end) {
    Calendar start = org.apache.commons.lang.time.DateUtils.toCalendar(begin);
    start.set(Calendar.MILLISECOND, 0);
    start.set(Calendar.SECOND, 0);
    start.set(Calendar.MINUTE, 0);
    start.set(Calendar.HOUR_OF_DAY, 0);

    Calendar finish = org.apache.commons.lang.time.DateUtils.toCalendar(end);
    finish.set(Calendar.MILLISECOND, 999);
    finish.set(Calendar.SECOND, 59);
    finish.set(Calendar.MINUTE, 59);
    finish.set(Calendar.HOUR_OF_DAY, 23);

    long delta = finish.getTimeInMillis() - start.getTimeInMillis();
    return (int) Math.ceil(delta / (1000.0 * 60 * 60 * 24));
}

мое лучшее решение (до сих пор) для расчета разницы в количестве дней:

//  This assumes that you already have two Date objects: startDate, endDate
//  Also, that you want to ignore any time portions

Calendar startCale=new GregorianCalendar();
Calendar endCal=new GregorianCalendar();

startCal.setTime(startDate);
endCal.setTime(endDate);

endCal.add(Calendar.YEAR,-startCal.get(Calendar.YEAR));
endCal.add(Calendar.MONTH,-startCal.get(Calendar.Month));
endCal.add(Calendar.DATE,-startCal.get(Calendar.DATE));

int daysDifference=endCal.get(Calendar.DAY_OF_YEAR);

заметим, однако, что это предполагает меньше, чем разница в год!

Если вам надоело возиться с java, вы можете просто отправить его в db2 как часть вашего запроса:

select date1, date2, days(date1) - days(date2) from table

вернет date1, date2 и разницу в днях между ними.