2014-10-16 137 views
9

我想检查日期是否包含2月29日。Java 8日期时间检查期间是否包含特定日期

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

我尝试:

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

    } 

beginDate但和maturity是从类型LocalDate 所以方法.isAfter.isBefore不能使用。

beginDate是15.01.2012
maturity是二零一三年一月二十○日

在此期间2月29日存在

解决方案

我终于找到解决方案:

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

只是检查二月月的最后日期 – Roshan 2014-10-16 12:09:57

+0

它是一个乔达时间或Java 8时API的问题吗?答案可能会有所不同...... – assylias 2014-10-16 14:00:41

+0

@assylias Java 8.谢谢:-) – YvesHendseth 2014-10-16 14:06:37

回答

1

您是否尝试过使用分别toDateTimeAtStartOfDaytoDateTime转换LocalDateMonthDayDateTime

如果年份不是闰年,您需要测试这是否会导致错误。它可能。

1

如何创建一个间隔并检查?喜欢的东西:

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

它会在2月29日到期的时候失败 – YvesHendseth 2014-10-16 12:26:19

+0

确实如此,并且检查两者都很难看。 : -/ – 2014-10-16 12:30:33

3

一种方法是创建一个TemporalAdjuster返回接下来的2月29日,检查maturity之前或在该日期之后。示例(未测试):

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

并且代码:

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

谢谢!我会明天测试:-) – YvesHendseth 2014-10-16 14:41:05

1

我这样想在测试用例条款。 beginDateendDate的值是什么会导致这种方法返回true或false?

例如,如果他们在同一年?也许这两个值都在2月29日的同一侧,或者它们跨越了它。

如果他们在不同的年份呢?如果那些年份相邻,或者如果有其他年份呢?也许这些干涉的年代都不是闰年。

然后你可以在这种情况下做什么,把这些情况的例子,然后写一个方法,调整它,直到所有的断言通过。

以下是您可以采取的方法。您可能希望添加beginDate和/或maturity闰日登陆的案例。

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

我可以建议你下一个解决方案,不用其他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

你确定:'nearestLeapYear =(yearTo/4)* 4;'? 1900年不是一个闰年,例如...使用内置的方法可能是比手动更好的方法。 – assylias 2014-10-16 21:36:10

相关问题