Android / Java - Ngày khác biệt tính theo ngày


80

Tôi đang nhận được ngày hiện tại (ở định dạng 31/12/1999 tức là mm / dd / yyyy) bằng cách sử dụng mã dưới đây:

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

và tôi đang có một ngày khác có định dạng là: 2010-08-25 (tức là yyyy / mm / dd),

vì vậy tôi muốn tìm sự khác biệt giữa ngày trong số ngày, làm thế nào để tìm sự khác biệt trong ngày?

(Nói cách khác, tôi muốn tìm sự khác biệt giữa NGÀY HIỆN TẠI - ngày được định dạng yyyy / mm / dd )


Mã này sử dụng các lớp date-time cũ rắc rối hiện được thay thế bởi các lớp java.time. Đối với Java và Android cũ hơn, hãy xem các dự án ThreeTen-BackportThreeTenABP .
Basil Bourque

Câu hỏi tương tự, nhưng sử dụng những khoảnh khắc chứ không phải là toàn bộ ngày: ngày chênh lệch trong ngày, trong Android
Basil Bourque

Câu trả lời:


126

Không thực sự là một phương pháp đáng tin cậy, tốt hơn khi sử dụng 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

Đây là một ước tính gần đúng ...

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

Để phân tích cú pháp ngày từ một chuỗi, bạn có thể sử dụng

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

Mặc dù, vì bạn chắc chắn về định dạng ngày tháng ... Bạn cũng có thể thực hiện Integer.parseInt()trên các Chuỗi con của nó để lấy các giá trị số của chúng.


@stOle thanx, nhưng tôi đang gặp cả ngày trong chuỗi, vì vậy làm thế nào để làm điều đó, xin cho tôi biết một cách chi tiết, xin
Paresh Mayani

1
@stOle không nhận được câu trả lời chính xác, có thể do lỗi nhỏ trong mã của bạn, tôi đang nhận được khoảng cách 274 ngày ngay cả khi tôi đặt String strThatDay = "2010/10/03" ;, chỉ cần 1 ngày, thanx để được hỗ trợ
Paresh Mayani

@Paresh, tôi rất tiếc, ("yyyy/mm/dd");nên được thay thế bằng ("yyyy/MM/dd");Nó viết hoa M cho Tháng, Viết thường cho Phút. Đã sửa.
st0le

1
@Gevorg, tôi đã giới thiệu nó. :) Me Gusta JodaTime
st0le 10/02/12

3
Đôi khi mã này sẽ bị nghỉ một ngày do các vấn đề làm tròn (thiếu mã) khi chia mili giây. Điều này phù hợp với tôi:Math.round(millisBetweenDates * 1f / TimeUnit.MILLISECONDS.convert(1, TimeUnit.DAYS));
Ciske Boekelo

83

Đây KHÔNG phải là công việc của tôi, tìm thấy câu trả lời ở đây . không muốn một liên kết bị hỏng trong tương lai :).

Điều quan trọng là dòng này để tính đến cài đặt ánh sáng ban ngày, tham khảo Mã đầy đủ.

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

hoặc thử đi qua TimeZone như một tham số để daysBetween()và cuộc gọi setTimeZone()trong sDateeDateđối tượng.

Vì vậy, đây là:

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 () lấy từ đây

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

Các đặc điểm: Tìm sự khác biệt giữa hai ngày không đơn giản bằng việc trừ hai ngày và chia kết quả cho (24 * 60 * 60 * 1000). Thật sai lầm!

Ví dụ: Sự khác biệt giữa hai ngày 24/03/2007 và 25/03/2007 phải là 1 ngày; Tuy nhiên, sử dụng phương pháp trên, ở Vương quốc Anh, bạn sẽ nhận được 0 ngày!

Xem cho chính mình (mã bên dưới). Đi theo cách mili giây sẽ dẫn đến lỗi làm tròn số và chúng trở nên rõ ràng nhất khi bạn có một số thứ như Giờ tiết kiệm ánh sáng ban ngày xuất hiện trong hình.

Mã đầy đủ:

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) {
  ...
}

ĐẦU RA:

Thủ công - Các ngày từ: 01-01-2007 đến 02-01-2007 là: 1

Dương lịch - Các ngày từ: 01/01/2007 đến 02/01/2007 là: 1


Thủ công - Các ngày từ: 24 tháng 3 năm 2007 đến ngày 25 tháng 3 năm 2007 là: 0

Lịch - Các ngày từ: 24 tháng 3 năm 2007 đến 25 tháng 3 năm 2007 là: 1


Đồng ý. Sử dụng các phương pháp cấp cao nhất Bạn đang nhận được các giải pháp đáng tin cậy và thanh lịch hơn. Cảm ơn!
Roger Alien

Đối với phương pháp: ngày Giữa nếu ngày là 15:00 ngày 24 tháng 7 năm 2012 và ngày kết thúc là 16:00 ngày 24 tháng 7 năm 2012 - thì ngày trước ngày kết thúc, TUY NHIÊN không phải là cả ngày, mà chỉ là một giờ. Tôi có thiếu thứ gì đó không hay kết quả từ daysBetween sẽ sai đối với trường hợp này (vì kết quả mong đợi là 0 nhưng với phép tính đã cho sẽ cho kết quả là 1 thay vì 0)?
AgentKnopf,

@Zainodis, Tôi đã cập nhật mã chưa. tôi đoán điều này sẽ giải quyết vấn đề.
Samuel,

@SamQuest Cảm ơn bạn đã cập nhật! Tôi đã thực hiện một cách tiếp cận ngây thơ hơn: Vòng lặp while với sDate.before (eDate) bị dừng và kết quả trả về, nếu bắt đầu và kết thúc cùng ngày, tháng và năm. điều này cũng đảm bảo rằng nếu trong lần lặp đầu tiên bắt đầu và kết thúc cùng một ngày / tháng / năm (mặc dù bắt đầu khôn ngoan về thời gian trước khi kết thúc) thì số 0 được trả về chính xác.
AgentKnopf,

Ngài xứng đáng nhận được Chuông!
marienke

38

Hầu hết các câu trả lời đều tốt và phù hợp với vấn đề của bạn về

vì vậy tôi muốn tìm sự khác biệt giữa ngày theo số ngày, làm cách nào để tìm sự khác biệt trong số ngày?

Tôi đề xuất cách tiếp cận rất đơn giản và dễ hiểu này đảm bảo cung cấp cho bạn sự khác biệt chính xác trong bất kỳ múi giờ nào:

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

Và đó là nó!


Điều này cũng làm việc cho tôi .. Những người khác cách quá phức tạp và cách để chính xác :)
Siddharth

1
Sẽ tốt hơn nếu bạn trừ trước và chia sau để ngăn chia hai lần.
ravindu1024

@ ravindu1024 Làm như vậy sẽ tạo ra sự khác biệt là +1 nếu ngày bắt đầu nhỏ hơn ngày kết thúc. Có sự khác biệt +1 trong trường hợp này. Có thể được giải quyết bằng cách thêm -1 vào câu trả lời.
sHOLE

@sHOLE như thế nào? Điều tôi đang nói là bạn nên làm (t1-t2) / C thay vì t1 / C - t2 / C. Vì cả t1 / C và t2 / C đều không bằng 0, tôi không thể hiểu điều đó sẽ ảnh hưởng đến câu trả lời như thế nào.
ravindu1024

@ ravindu1024 Tôi hiểu bạn đang muốn nói gì và cũng tự hỏi khi đọc câu trả lời này. Chỉ sau khi thực hiện, tôi mới nhận thấy tại sao nó không được thực hiện theo cách đó (lý do tôi đã đề cập ở trên).
sHOLE

25

Sử dụng API jodatime

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

trong đó 'bắt đầu' và 'kết thúc' là các đối tượng DateTime của bạn . Để phân tích cú pháp chuỗi ngày của bạn thành các đối tượng DateTime, hãy sử dụng phương thức parseDateTime

Ngoài ra còn có một thư viện JodaTime dành riêng cho Android .


3
thanx cho sự ủng hộ, nhưng không hạnh phúc để sử dụng API khác nếu nó được thực hiện với mã Android / JAVA
Paresh Mayani

2
+1 cho Joda. API Lịch Java là một mớ hỗn độn khủng khiếp và Joda rất sạch và đẹp.
LuxuryMode

JodaTime đưa ra một số lỗi với một số thiết bị trong Android, tôi không biết tại sao, tôi gặp một số vấn đề với điều đó
josemwarrior

1
Thư viện thời gian Joda sẽ thêm 4744 phương thức vào dự án của bạn. Hãy lựa chọn một cách khôn ngoan nếu bạn muốn tránh giới hạn 65 nghìn phương pháp.
Lior Iluz

14

Đoạn này tính đến thời gian tiết kiệm ánh sáng ban ngày và là 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));
}

6

Đây là phép tính đơn giản và tốt nhất cho tôi và có thể cho bạn.

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

@PareshMayani chỉ kiểm tra trong log mèo
Rishi Gautam

3

Các Correct Waytừ câu trả lời Sam Quest của chỉ hoạt động nếu ngày đầu tiên là sớm hơn so với thứ hai. Hơn nữa, nó sẽ trả về 1 nếu hai ngày trong vòng một ngày.

Đây là giải pháp phù hợp nhất với tôi. Cũng giống như hầu hết các giải pháp khác, nó sẽ vẫn hiển thị kết quả không chính xác vào hai ngày trong năm do bù đắp tiết kiệm ánh sáng ngày sai.

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

cách tốt nhất và dễ nhất để làm điều này

  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

tl; dr

ChronoUnit.DAYS.between( 
    LocalDate.parse( "1999-12-28" ) , 
    LocalDate.parse( "12/31/1999" , DateTimeFormatter.ofPattern( "MM/dd/yyyy" ) ) 
)

Chi tiết

Các câu trả lời khác đã lỗi thời. Các lớp date-time cũ đi kèm với các phiên bản Java sớm nhất đã được chứng minh là được thiết kế kém, khó hiểu và rắc rối. Tránh chúng.

java.time

Dự án Joda-Time đã rất thành công khi thay thế cho các lớp cũ đó. Các lớp này cung cấp nguồn cảm hứng cho khung công tác java.time được tích hợp trong Java 8 trở lên.

Phần lớn chức năng java.time được chuyển ngược sang Java 6 & 7 trong ThreeTen-Backport và được điều chỉnh thêm cho Android trong ThreeTenABP .

LocalDate

Các LocalDatelớp đại diện cho một giá trị ngày tháng chỉ mà không cần thời gian của ngày và không có múi giờ.

Phân tích cú pháp chuỗi

Nếu chuỗi đầu vào của bạn ở định dạng ISO 8601 tiêu chuẩn , LocalDatelớp có thể phân tích cú pháp trực tiếp chuỗi.

LocalDate start = LocalDate.parse( "1999-12-28" );

Nếu không ở định dạng ISO 8601, hãy xác định mẫu định dạng với DateTimeFormatter.

String input = "12/31/1999";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "MM/dd/yyyy" );
LocalDate stop = LocalDate.parse( input , formatter );

Những ngày đã qua qua ChronoUnit

Bây giờ, hãy đếm số ngày đã trôi qua giữa cặp LocalDateđối tượng đó. Các ChronoUnittính toán của enum thời gian trôi qua.

long totalDays = ChronoUnit.DAYS.between( start , stop ) ; 

Nếu bạn không quen với Java enums, hãy biết rằng chúng mạnh mẽ và hữu ích hơn nhiều so với enum thông thường trong hầu hết các ngôn ngữ lập trình khác. Xem Enumtài liệu lớp, Hướng dẫn OracleWikipedia để tìm hiểu thêm.


Giới thiệu về java.time

Các java.time khung được xây dựng vào Java 8 và sau đó. Những lớp học thay thế cái cũ phiền hà di sản lớp học ngày thời gian như java.util.Date, Calendar, & SimpleDateFormat.

Các Joda thời gian dự án, bây giờ trong chế độ bảo trì , khuyên chuyển đổi sang các java.time lớp.

Để tìm hiểu thêm, hãy xem Hướng dẫn Oracle . Và tìm kiếm Stack Overflow cho nhiều ví dụ và giải thích. Đặc điểm kỹ thuật là JSR 310 .

Lấy các lớp java.time ở đâu?

  • Java SE 8 SE 9 trở lên
    • Được xây dựng trong.
    • Một phần của API Java tiêu chuẩn với một triển khai đóng gói.
    • Java 9 bổ sung một số tính năng nhỏ và các bản sửa lỗi.
  • Java SE 6 SE 7
    • Phần lớn chức năng java.time được chuyển ngược sang Java 6 & 7 trong ThreeTen-Backport .
  • Android

Các ThreeTen-Extra dự án mở rộng java.time với các lớp bổ sung. Dự án này là cơ sở chứng minh cho những bổ sung có thể có trong tương lai cho java.time. Bạn có thể tìm thấy một số các lớp học hữu ích ở đây chẳng hạn như Interval, YearWeek, YearQuarter, và nhiều hơn nữa .


java.time.LocalDate không được hỗ trợ trong Android
Mahdi Astanei

1
@MahdiAstanei Đọc lại đoạn thứ ba của tôi về thư viện ThreeTenABP dành cho Android. Rất đáng để thêm vào ứng dụng của bạn vì các lớp ngày-giờ cũ thực sự rất tệ.
Basil Bourque vào

2

Sử dụng các chức năng sau:

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

Có một giải pháp đơn giản, ít nhất đối với tôi, là giải pháp khả thi duy nhất.

Vấn đề là tất cả các câu trả lời tôi thấy đang bị quăng xung quanh - sử dụng Joda, hoặc Lịch, hoặc Ngày, hoặc bất cứ điều gì - chỉ tính đến lượng mili giây. Họ sẽ đếm số chu kỳ 24 giờ giữa hai ngày , thay vì số ngày thực tế . Vì vậy, từ 11 giờ đêm ngày 1 tháng 1 đến 1 giờ sáng ngày 2 tháng 1 sẽ trả về 0 ngày.

Để đếm số ngày thực tế giữa startDateendDate, chỉ cần thực hiện:

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

Điều này sẽ trả về "1" từ ngày 2 tháng 1 đến ngày 1 tháng 1. Nếu bạn cần đếm ngày kết thúc, chỉ cần thêm 1 vào daysBetween(Tôi cần làm điều đó trong mã của mình vì tôi muốn đếm tổng số ngày trong phạm vi).

Điều này hơi giống với những gì Daniel đã đề xuất nhưng tôi cho là mã nhỏ hơn.


2

Tất cả các giải pháp này đều mắc phải một trong hai vấn đề. Giải pháp không hoàn toàn chính xác do lỗi làm tròn, ngày nhuận và giây, v.v. hoặc bạn sẽ lặp lại số ngày ở giữa hai ngày không xác định của mình.

Giải pháp này giải quyết vấn đề đầu tiên và cải thiện vấn đề thứ hai theo hệ số khoảng 365, tốt hơn nếu bạn biết phạm vi tối đa của mình là bao nhiêu.

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

Nếu bạn cần các ngày giữa các ngày (không bao gồm ngày sau đó), chỉ cần loại bỏ + 1khi bạn thấy endDay - startDay + 1.


1

Một cách khác:

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

vui lòng đưa ra nhận xét về mã bạn đã cung cấp. để mọi người hiểu ý nghĩa mã của bạn.
Abed Putra

1

sử dụng các chức năng này

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

Mã này sử dụng các lớp date-time cũ rắc rối hiện được thay thế bởi các lớp java.time. Đối với Java và Android cũ hơn, hãy xem các dự án ThreeTen-BackportThreeTenABP .
Basil Bourque

Lớp lịch có phải là lớp ngày-giờ cũ không?
neal zedlav

Có, bất kỳ lớp nào liên quan đến ngày-giờ được tìm thấy bên ngoài java.timegói bây giờ là kế thừa và nên tránh. Điều này bao gồm Datevà và Calendarvà các lớp java.sql. Xem Hướng dẫn Oracle.
Basil Bourque

1
        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

Tôi đã tìm thấy một cách rất dễ dàng để thực hiện việc này và đó là những gì tôi đang sử dụng trong ứng dụng của mình.

Giả sử bạn có ngày trong đối tượng Thời gian (hoặc bất cứ điều gì, chúng tôi chỉ cần mili giây):

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

Joda-Time

Cách tốt nhất là sử dụng Joda-Time , thư viện mã nguồn mở rất thành công mà bạn sẽ thêm vào dự án của mình.

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

Nếu bạn đang sử dụng Android Studio , rất dễ dàng thêm joda-time. Trong build.gradle (ứng dụng) của bạn:

dependencies {
  compile 'joda-time:joda-time:2.4'
  compile 'joda-time:joda-time:2.4'
  compile 'joda-time:joda-time:2.2'
}

Câu trả lời tốt. Lưu ý rằng việc gọi toStringvào Durationtạo ra một biểu diễn Chuỗi ở một trong các định dạng tiêu chuẩn ISO 8601PnYnMnDTnHnMnS ,. Các Pdấu hiệu đánh dấu sự bắt đầu, trong khi dấu Tphân cách năm-tháng-ngày với giờ-phút-giây. Vì vậy, P3Dlà ba ngày, và P3DT12Hlà ngày ba tuổi rưỡi.
Basil Bourque

2
Thư viện thời gian Joda sẽ thêm 4744 phương thức vào dự án của bạn. Hãy lựa chọn một cách khôn ngoan nếu bạn muốn tránh giới hạn 65 nghìn phương pháp.
Lior Iluz

Điều này cần được thay đổi thành định dạng DateTimeFormatter = DateTimeFormat.forPattern ("yyyy-MM-dd")
sb_269

0
        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));
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.