2014-10-16 16 views
9

Tôi muốn kiểm tra xem một khoảng thời gian có đến ngày 29 tháng 2 hay không.Java 8 Kiểm tra ngày giờ nếu khoảng thời gian chứa ngày cụ thể

private static final MonthDay LEAP = MonthDay.of(Month.FEBRUARY, 29); 

tôi đã cố gắng:

if (LEAP.isAfter(beginDate) && LEAP.isBefore(maturity)) { 

    } 

nhưng beginDatematurity là từ loại LocalDate nên phương pháp .isAfter.isBefore không thể được sử dụng.

Ví dụ

beginDate là 2012/01/15
maturity là 2013/01/20

trong giai đoạn này các ngày 29 tháng 2 tồn tại

Giải pháp

tôi cuối cùng đã tìm thấy một giải pháp:

for (int i = beginDate.getYear(); i <= maturity.getYear(); i++) { 
    final Year year = Year.of(i); 
    if (year.isLeap()) { 
     if (beginDate.compareTo(LEAP.atYear(i)) <= 0 || maturity.compareTo(LEAP.atYear(i)) >= 0) { 
      minMaturity.plusDays(1); 
     } 
    } 
    return false; 
} 
+0

Chỉ cần kiểm tra ngày cuối cùng của tháng hai tháng – Roshan

+0

Có một thời gian Joda hoặc java 8 lần api câu hỏi? Câu trả lời có thể khác ... – assylias

+0

@assylias Java 8. Cảm ơn :-) – YvesHendseth

Trả lời

1

Các bạn đã thử chuyển đổi LocalDateMonthDay-DateTime sử dụng toDateTimeAtStartOfDaytoDateTime tương ứng?

Bạn cần kiểm tra xem điều này có mang lại kết quả đúng hay không khi năm không phải là năm nhuận. Nó có thể.

1

Làm cách nào để tạo Khoảng thời gian và kiểm tra? Một cái gì đó như:

LocalDate beginDate, maturity; 
    final Interval interval = new Interval(beginDate.toDateTimeAtStartOfDay(), maturity.toDateTimeAtStartOfDay()); 
    if (interval.contains(new DateTime(beginDate.getYear(), Month.FEBRUARY, 29, 0, 1)) || 
     interval.contains(new DateTime(maturity.getYear(), Month.FEBRUARY, 29, 0, 1))) { 
     // It does 
    } 
+2

nó sẽ thất bại khi ngày 29 tháng 2 là năm trưởng thành – YvesHendseth

+0

Đúng, và để kiểm tra cả hai là xấu xí. : -/ –

3

Một cách sẽ được để tạo ra một TemporalAdjuster mà trả về ngày 29 tháng 2 tới và kiểm tra xem maturity là trước hoặc sau ngày đó. Ví dụ (không kiểm tra):

public static TemporalAdjuster nextOrSame29Feb() { 
    return temporal -> { 
    LocalDate input = LocalDate.from(temporal); 
    if (input.isLeapYear()) { 
     LocalDate feb29 = input.with(MonthDay.of(FEBRUARY, 29)); 
     if (!input.isAfter(feb29)) return feb29; 
    } 
    for (int year = input.getYear() + 1; ; year++) { 
     if (Year.isLeap(year)) return LocalDate.of(year, FEBRUARY, 29); 
    } 
    }; 
} 

Và mã của bạn trở thành:

boolean contains29Feb = !maturity.isBefore(beginDate.with(nextOrSame29Feb())); 
+0

Cảm ơn! Tôi sẽ kiểm tra nó vào ngày mai :-) – YvesHendseth

1

Tôi thích nghĩ về trường hợp thử nghiệm. Giá trị nào cho beginDateendDate sẽ gây ra một phương thức trả về đúng hay sai?

Ví dụ: nếu chúng ở cùng năm? Có lẽ cả hai giá trị đều nằm trên cùng một bên của ngày 29 tháng 2 hoặc chúng có chiều dài.

Điều gì xảy ra nếu chúng ở các năm khác nhau? Điều gì xảy ra nếu những năm đó liền kề, hoặc nếu có những năm khác ở giữa? Có lẽ không có năm can thiệp nào thậm chí là năm nhuận.

Sau đó, bạn có thể làm gì trong trường hợp này được đặt cùng các ví dụ về các trường hợp này và sau đó viết một phương thức, điều chỉnh nó cho đến khi tất cả các xác nhận vượt qua.

Dưới đây là cách tiếp cận bạn có thể thực hiện. Bạn có thể muốn thêm các trường hợp trong đó beginDate và/hoặc maturity vào một ngày nhuận.

public class Q26403911 { 
    @Test 
    public void testContainsLeapYear() throws Exception { 
     Assert.assertTrue(isContainsLeapYear(LocalDate.of(1984, 2, 28), LocalDate.of(1984, 3, 1))); 
     Assert.assertFalse(isContainsLeapYear(LocalDate.of(1985, 2, 28), LocalDate.of(1985, 3, 1))); 
     Assert.assertFalse(isContainsLeapYear(LocalDate.of(1984, 2, 27), LocalDate.of(1984, 2, 28))); 
     Assert.assertFalse(isContainsLeapYear(LocalDate.of(1984, 3, 1), LocalDate.of(1984, 3, 2))); 
     Assert.assertTrue(isContainsLeapYear(LocalDate.of(1984, 2, 28), LocalDate.of(1985, 3, 1))); 
     Assert.assertTrue(isContainsLeapYear(LocalDate.of(1983, 3, 1), LocalDate.of(1984, 3, 1))); 
     Assert.assertFalse(isContainsLeapYear(LocalDate.of(1984, 3, 1), LocalDate.of(1985, 3, 1))); 
     Assert.assertFalse(isContainsLeapYear(LocalDate.of(1983, 2, 28), LocalDate.of(1984, 2, 28))); 
     Assert.assertTrue(isContainsLeapYear(LocalDate.of(1983, 3, 1), LocalDate.of(1985, 2, 28))); 
     Assert.assertFalse(isContainsLeapYear(LocalDate.of(1985, 3, 1), LocalDate.of(1987, 2, 28))); 
    } 

    public boolean isContainsLeapYear(LocalDate beginDate, LocalDate maturity) { 
     if (beginDate.getYear() == maturity.getYear()) 
     { 
      if (!Year.isLeap(beginDate.getYear())) 
      { 
       return false; 
      } 

      if (maturity.isBefore(LocalDate.of(beginDate.getYear(), Month.FEBRUARY, 29))) 
      { 
       return false; 
      } 

      if (beginDate.isAfter(LocalDate.of(maturity.getYear(), Month.FEBRUARY, 29))) 
      { 
       return false; 
      } 

      return true; 
     } 
     else if (Year.isLeap(beginDate.getYear()) 
         && !beginDate.isAfter(LocalDate.of(beginDate.getYear(), Month.FEBRUARY, 29))) 
     { 
      return true; 
     } 
     else if (Year.isLeap(maturity.getYear()) 
         && !maturity.isBefore(LocalDate.of(maturity.getYear(), Month.FEBRUARY, 29))) 
     { 
      return true; 
     } 
     else 
     { 
      for (int year = beginDate.getYear() + 1; year < maturity.getYear(); year++) 
      { 
       if (Year.isLeap(year)) 
       { 
        return true; 
       } 
      } 
     } 
     return false; 
    } 
} 
0

tôi có thể đề nghị bạn giải pháp tiếp theo, witout MonthDay

static int LEAP = 31 + 29; 

    public static boolean conatins29Feb(LocalDate dateFrom, LocalDate dateTo) 
    { 
     final int yearFrom = dateFrom.getYear(), 
       yearTo = dateTo.getYear(), 
       dayOfYearFrom = dateFrom.getDayOfYear(), 
       dayOfYearTo = dateTo.getDayOfYear(), 
       nearestLeapYear = (yearTo/4) * 4; // nearest to `dateTo` 

     return (yearFrom <= nearestLeapYear && yearTo >= nearestLeapYear) 
       && (yearFrom < nearestLeapYear || dayOfYearFrom <= LEAP) 
        && (yearTo > nearestLeapYear || dayOfYearTo >= LEAP); 
    } 
+0

Bạn có chắc chắn về: 'recentLeapYear = (yearTo/4) * 4;'? Ví dụ, năm 1900 không phải là một năm nhuận ... Sử dụng các phương pháp dựng sẵn có lẽ là một đặt cược tốt hơn so với việc thực hiện thủ công ... – assylias

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