2011-08-18 18 views

Odpowiedz

114

Na początek, powinieneś tylko traktować je jako ciągi, gdy musisz. W większości przypadków powinieneś pracować z nimi w typie danych, który faktycznie opisuje dane, z którymi pracujesz.

Polecam użyć Joda Time, który jest o wiele lepszym API niż Date/Calendar. Wygląda na to, że powinieneś użyć w tym przypadku typu LocalDate. Następnie można użyć:

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

wydaje się metoda ta jest wyłącznym i nie obejmuje, więc może chcieć dodać 1 do wyniku (lub dodać ** 25 ** (i nie 24) godzin do 'date2'), aby włączyć go. –

+0

@AlaaM .: Cóż, * jeśli * chcesz, aby było włączone. Gdybym został poproszony o liczbę dni między 24 grudnia a 25 grudnia, powiedziałbym 1, nie 2 ... (I OP wydaje się być wystarczająco szczęśliwy). –

+0

Tak, dlatego powiedziałem * może chcieć *. W moim przypadku musiałem wyświetlić "pozostałe dni do wygaśnięcia". Tak więc, moim zdaniem, ta sprawa powinna zawierać: –

8

oto mały program, który może pomóc:

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

Jedną z rzeczy, którą chciałbym edytować jest: '' ' publiczne długie dni pomiędzy (data d1, data d2) { powrót ((d2.getTime() - d1.getTime())/(1000 * 60 * 60 * 24)); } '' ' – iamtodor

34

wypróbować ten kod

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

tę funkcję

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

jak ta metoda obsłuży zmianę czasu letniego? – eldjon

+1

Ta formuła jest dobra, ale będzie mniej 1 dzień. Na przykład d1 = 2 stycznia 2016 r. I d2 = 1 stycznia 2016 r., Da ci 1 dzień zamiast 2 dni. – stanicmail

+4

@stanicmail Ale był TYLKO JEDEN dzień od 1 stycznia do 2 stycznia 2016! Chyba że wypiłeś za dużo na d0 = 31 grudnia 2015 r., Oczywiście. ;-) – tomorrow

-5

Jeśli” masz już dość rozmnażania z Javą, możesz se a do db2 jako część twojego zapytania:

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

zwróci datę1, datę2 i różnicę w dniach między tymi dwoma.

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

mnie najlepszym rozwiązaniem (do tej pory) do obliczania liczby dni różnicy:

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

Należy jednak pamiętać, że ta zakłada mniej niż rok różnicy!

1

Funkcja ta jest dobra dla mnie:

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

W Javie 8. Można użyć instancji Enum ChronoUnit obliczyć ilość czasu w różnych jednostkach (dni, miesiące, sekundy).

Dla przykładu:

ChronoUnit.DAYS.between(startDate,endDate) 
19

Znam ten wątek jest stary teraz dwa lata, wciąż nie widać poprawną odpowiedź tutaj.

Chyba, że ​​chcesz korzystać z Jody lub Java 8 i jeśli chcesz subtraktować daty, na które ma wpływ zmiana czasu.

Więc napisałem własne rozwiązanie. Ważnym aspektem jest to, że działa tylko jeśli naprawdę dbają tylko o terminach, ponieważ jest to konieczne, aby usunąć informację o czasie, więc jeśli chcesz coś podobnego 25.06.2014 - 01.01.2010 = 1636, to powinien działać niezależnie od DST:

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

W czasie jest zawsze 00:00:00, używając podwójnego, a następnie Math.round() powinno pomóc zignorować brakujące 60000ms (1 godzina), gdy idziesz od zimy do lata, a także dodatkową godzinę, jeśli idziesz od lata do zimy.

ten mały test JUnit4 używam to udowodnić:

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

... lub jeśli chcesz zobaczyć, co robi 'życie', wymień twierdzenie ze tylko:

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

... i to wyjście powinno wyglądać następująco:

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

Jestem naprawdę naprawdę naprawdę nowego w Javie, więc jestem pewien, że istnieje W jeszcze lepszy sposób robienia tego, co proponuję.

Miałem ten sam popyt i zrobiłem to z różnicą między DAYOFYEAR z dwóch dat. Wydaje się, że jest to łatwiejszy sposób ...

Nie mogę ocenić tego rozwiązania pod względem wydajności i stabilności, ale uważam, że jest w porządku.

tutaj:

 
    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()) + "."); 



    } 

W tym przypadku wyjście byłoby (pamiętając, że używam Format daty dd/mm/rrrr):

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

To nie działa, ponieważ informuje tylko o różnicy między dniami w roku, a nie o całkowitej liczbie uruchomionych dni. – Stosh15

Powiązane problemy