2011-09-18 35 views
9

Tôi đang viết một chương trình có nghĩa vụ tính toán các tháng giữa 2 ngày đã cho và trả về giá trị cho chương trình. Ví dụ, nếu tôi phải tính toán số tháng giữa ngày 01 tháng 4 và 30 tháng 6 (đó là một phần tư, 3 tháng), và tôi sử dụng đoạn mã sau:Cách tính chênh lệch CHỈ trong tháng sử dụng Joda API của Java

DateTime start = new DateTime().withDate(2011, 4, 1); 
    DateTime end = new DateTime().withDate(2011, 6, 30); 

    Months mt = Months.monthsBetween(start, end); 
    int monthDiff = mt.getMonths(); 

Sử dụng này, tôi vẫn nhận được " 2 "là số tháng, trong khi đó thực sự là" 3 "tháng. Đây là một ví dụ về những gì tôi muốn. Tôi chỉ tính số tháng (tức là từ ngày 1 của tháng bắt đầu t ngày cuối cùng của tháng kết thúc) và tôi không cần phân tích bổ sung như ngày, tuần, giờ, v.v. Làm cách nào để đạt được điều này?

Mọi trợ giúp sẽ được đánh giá cao.

+3

Không thể chờ đợi để đọc các câu trả lời từ Jon Skeet, các Stackoverflow và ngày Chuyên gia API;) – DaveFar

+0

Tôi tin câu trả lời đúng giờ của Yoda là chính xác. Từ ngày 1 tháng 4 đến (nhưng không bao gồm) ngày 30 tháng 6 sẽ là _almost_ 3 tháng. Tôi nghĩ cả hai ngày đều có cùng thời gian (00:00) và do đó ngày 30 tháng 6 không thực sự được bao gồm trong phạm vi. – extraneon

+0

@extraneon - Đúng vậy. Thời gian hiển thị là 2 tháng, 4 tuần và 1 ngày. –

Trả lời

9
DateTime start = new DateTime().withDate(2011, 4, 1); 
DateTime end = new DateTime().withDate(2011, 6, 30); 
Period p = new Period(start, end, PeriodType.months().withDaysRemoved()); 
int months = p.getMonths() + 1; 

Bạn cần phần withDaysRemoved() để đảm bảo rằng việc thêm một đến số tháng hoạt động. Nếu không, hai ngày như 2011-04-152011-06-14 sẽ vẫn dẫn đến câu trả lời là 2

+0

Điều này có vẻ hoạt động tốt. Tôi sẽ thực hiện thêm một số kiểm tra và kiểm tra –

+0

Tính năng này không hoạt động. Ví dụ: không thành công trong 2015-06-10 và 2015-07-01 ("tháng" kết thúc bằng 1 thay vì 2). Bạn có thể tìm thấy giải pháp chính xác tại đây: http://stackoverflow.com/a/1086432/1369016 – Tiago

3

Tại sao bạn mong đợi câu trả lời là 3 months? Câu trả lời chính xác là hai tháng và một chút, sau đó kết quả trong số hai tháng bạn đang nhận được.

Nếu bạn muốn số tháng được "chạm" vào khoảng thời gian này, đây là một câu hỏi hoàn toàn khác. Chỉ cần thêm 1 vào kết quả của sự khác biệt.

+0

Vấn đề là tùy thuộc vào ngày được cung cấp, việc thêm một tháng có thể không hoạt động. –

+0

Tôi không định thêm một tháng vào một ngày, nhưng để thêm 1 vào biến 'monthDiff' trong câu hỏi. –

+1

Tôi biết. Nếu ngày là 2011-04-15 và 2011-06-14, điều đó sẽ thất bại vì getMonths() sẽ trả lại 1. –

1

Thuật toán Joda được tính khác biệt chính xác giữa hai ngày này. pseudo-code này sẽ là cách đơn giản nhất để giải thích cách hoạt động:

// (1) 
monthsBetween(2011.6.14, 2011.4.15) = 1 
monthsBetween(2011.6.15, 2011.4.15) = 2 
// (2) 
monthsBetween(2011.6.30, 2011.4.1) = 2 
monthsBetween(2011.7.1, 2011.4.1) = 3 

Để làm những gì bạn muốn, bạn cần phải "cải thiện" thuật toán Joda:

  • Đếm khoảng cách giữa hai ngày (sử dụng bình thường monthsBetween)
  • Nếu bạn có tình huống cụ thể: ngày cuối cùng của tháng trong một ngày và ngày đầu tiên của tháng trong ngày thứ hai, hãy thêm +1 vào kết quả cuối cùng.
1

Hãy y1m1 là năm và tháng kể từ ngày bắt đầu, và y2m2 là năm và tháng kể từ ngày kết thúc. Sau đó, số tháng giữa bắt đầu và kết thúc, trong đó có những tháng ngày bắt đầu và kết thúc là

(y2 - y1) * 12 + (m2 - m1) + 1 
2
Months mt = Months.monthsBetween(
    start.monthOfYear().roundFloorCopy(), 
    end.monthOfYear().roundCeilingCopy() 
); 
1
DateTime start = new DateTime().withDate(2011, 4, 1); 
     DateTime end = new DateTime().withDate(2011, 2, 1); 
     Period p = new Period(start, end, PeriodType.months().withDaysRemoved()); 
     int months = p.getMonths(); 
     System.out.println(months); 


wrong output in this case 
Các vấn đề liên quan