2011-08-18 71 views

Trả lời

114

Để bắt đầu, bạn chỉ nên chỉ đối phó với chúng dưới dạng chuỗi khi bạn cần. Hầu hết thời gian bạn nên làm việc với họ trong một kiểu dữ liệu mà thực sự mô tả dữ liệu bạn đang làm việc.

Tôi khuyên bạn nên sử dụng Joda Time, API tốt hơn nhiều so với Date/Calendar. Có vẻ như bạn nên sử dụng loại LocalDate trong trường hợp này. Sau đó bạn có thể sử dụng:

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

Dường như phương pháp này là độc quyền và không bao gồm, vì vậy có thể muốn thêm 1 vào kết quả (hoặc thêm ** 25 ** (và không phải 24) giờ vào 'date2') để làm cho nó bao gồm. –

+0

@AlaaM .: Vâng, * nếu * bạn muốn làm cho nó bao gồm. Nếu tôi được hỏi số ngày từ ngày 24 tháng 12 đến ngày 25 tháng 12, tôi muốn nói 1, không phải 2 ... (Và OP có vẻ đủ hạnh phúc.) –

+0

Vâng, đó là lý do tôi nói * có thể muốn *. Trong trường hợp của tôi, tôi cần hiển thị "ngày còn lại cho đến hết hạn". Vì vậy, theo ý kiến ​​của tôi trường hợp này nên được bao gồm –

8

đây là một chương trình nhỏ có thể giúp bạn:

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

Điều tôi sẽ chỉnh sửa là: '' ' ngày dài công cộngĐối sánh (Ngày d1, Ngày d2) { return ((d2.getTime() - d1.getTime())/(1000 * 60 * 60 * 24)); } '' ' – iamtodor

34

thử mã này

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

chức năng này

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

phương pháp này sẽ xử lý thay đổi tiết kiệm ánh sáng ban ngày như thế nào? – eldjon

+1

Công thức này là tốt nhưng nó sẽ ít hơn 1 ngày. Ví dụ: d1 = ngày 2 tháng 1 năm 2016 và d2 = ngày 1 tháng 1 năm 2016, nó sẽ cung cấp cho bạn 1 ngày thay vì 2 ngày. – stanicmail

+4

@stanicmail Nhưng chỉ có MỘT ngày từ ngày 1 tháng 1 đến ngày 2 tháng 1 năm 2016! Trừ khi bạn đã uống quá nhiều vào d0 = 31 tháng 12 năm 2015, tất nhiên. ;-) – tomorrow

-5

Nếu bạn' lại bệnh rối tung với java bạn chỉ có thể se nd it to db2 như một phần của truy vấn của bạn:

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

sẽ trả về ngày1, ngày 2 và sự khác biệt về ngày giữa hai ngày.

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

giải pháp tốt nhất (cho đến nay) để tính số ngày chênh lệch của tôi:

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

Lưu ý, tuy nhiên, điều này giả định ít hơn sự khác biệt một năm!

1

Chức năng này là tốt cho tôi:

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

Trong Java 8. Bạn có thể sử dụng trường hợp của Enum ChronoUnit để tính toán số lượng thời gian trong các đơn vị khác nhau (ngày, tháng, giây).

Ví dụ:

ChronoUnit.DAYS.between(startDate,endDate) 
19

Tôi biết chủ đề này là hai năm cũ bây giờ, tôi vẫn không thấy một câu trả lời đúng ở đây.

Trừ khi bạn muốn sử dụng Joda hoặc có Java 8 và nếu bạn cần phải rút ngắn ngày bị ảnh hưởng bởi tiết kiệm ánh sáng ban ngày.

Vì vậy, tôi đã viết giải pháp của riêng mình. Khía cạnh quan trọng là nó chỉ có tác dụng nếu bạn thực sự chỉ quan tâm đến số ngày bởi vì nó là cần thiết để loại bỏ các thông tin thời gian, vì vậy nếu bạn muốn một cái gì đó giống như 25.06.2014 - 01.01.2010 = 1636, điều này sẽ làm việc không phụ thuộc vào 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; 
} 

Khi thời gian luôn luôn là 00:00:00, sử dụng double và sau đó Math.round() sẽ giúp bỏ qua 60000ms mất tích (1 giờ) khi đi từ mùa đông đến mùa hè cũng như thêm giờ nếu đi từ mùa hè đến mùa đông.

Đây là một thử nghiệm Junit4 nhỏ tôi sử dụng để chứng minh điều đó:

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

... hoặc nếu bạn muốn xem những gì nó làm 'cuộc sống', thay thế sự khẳng định chỉ với:

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

... và đây là những gì đầu ra sẽ giống như thế:

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

tôi thực sự thực sự thực sự mới tại Java, vì vậy tôi chắc chắn rằng có một n thậm chí tốt hơn cách để làm những gì tôi đang đề xuất.

Tôi đã có nhu cầu tương tự này và tôi đã làm điều đó bằng cách sử dụng sự khác biệt giữa DAYOFYEAR trong hai ngày. Có vẻ như một cách dễ dàng hơn để thực hiện điều đó ...

Tôi thực sự không thể đánh giá giải pháp này về hiệu suất và độ ổn định, nhưng tôi nghĩ điều đó là ổn.

đây:

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



    } 

Trong trường hợp này, sản lượng sẽ là (ghi nhớ rằng tôi đang sử dụng DD Định dạng ngày/tháng/năm):

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

Điều này không có tác dụng vì nó chỉ cho bạn biết sự khác biệt giữa các ngày trong năm chứ không phải tổng số ngày chạy. – Stosh15

Các vấn đề liên quan