2014-10-16 7 views
9

Chcę sprawdzić, czy okres do daty zawiera 29 lutego.Java 8 DateTime sprawdź, czy okres zawiera określony dzień

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

próbowałem:

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

    } 

ale beginDate i maturity są od rodzaju LocalDate więc metody .isAfter i .isBefore nie może być używany.

Przykład

beginDate jest 15.01.2012
maturity jest 20.01.2013

w tym okresie 29 lutego istnieje

Rozwiązanie

I wreszcie znaleźć rozwiązanie:

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

Wystarczy sprawdzić datę ostatniej Lut miesiąca – Roshan

+0

jest to czas Joda lub Java 8 czas api pytanie? Odpowiedź może być inna ... – assylias

+0

@assylias Java 8. Dzięki :-) – YvesHendseth

Odpowiedz

1

Czy próbowałeś przekształcenie LocalDate i MonthDay do DateTime użyciu toDateTimeAtStartOfDay i toDateTime odpowiednio?

Musisz sprawdzić, czy może to spowodować, że rok nie jest rokiem przestępnym. Może.

1

Co powiesz na utworzenie interwału i sprawdzenie, czy? Coś jak:

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

to się nie powiedzie, gdy 29 lutego jest w roku zapadalności – YvesHendseth

+0

To prawda, i aby sprawdzić oba są brzydkie. : -/ –

3

Jeden sposób byłoby utworzyć TemporalAdjuster że zwraca następny 29 lutego i sprawdzić, czy maturity jest przed lub po tej dacie. Przykład (nie testowane):

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

a kod staje:

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

Dzięki! Przetestuję to jutro :-) – YvesHendseth

1

Lubię myśleć w kategoriach przypadków testowych. Jakie wartości dla beginDate i endDate spowodują, że taka metoda zwróci wartość true lub false?

Na przykład, jeśli są w tym samym roku? Być może obie wartości są po tej samej stronie 29 lutego, lub obejmują je.

Co, jeśli są w różnych latach? Co, jeśli te lata sąsiadują ze sobą lub czy są inne lata pomiędzy? Być może żaden z upływających lat nie jest nawet latami przestępnymi.

Co można wtedy zrobić w tego rodzaju scenariuszu składa się przykłady tych przypadków, a następnie napisać metodę, dostosowując go, aż wszystkie dowody przeminą.

Poniżej przedstawiono podejście, które można zastosować. Możesz dodać przypadki, w których beginDate i/lub maturity wylądują w dniu przestępnym.

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

mogę zaproponować ci następne rozwiązanie, 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

Czy jesteś pewien o: 'nearestLeapYear = (yearTo/4) * 4;'? Rok 1900 nie był rokiem przestępnym ... Używanie wbudowanych metod jest prawdopodobnie lepszym rozwiązaniem niż robienie tego ręcznie ... – assylias