5

我想从计算两个日期之间的完整天数中排除 2 月 29 日。不包括区间的角值。

测试场景:

1 March 2012 - 28th February 2012  = should give 0 days.
1 March 2012 - 26th February 2012  = should give 2 days.
1 March 2013 - 28th February 2012  = should give 365 days and not 366 days.
1 March 2017 - 28th February 2012  = should give 365*5 =1825 days and not 1827 days.

目前我解析年份并检查日期之间是否有闰年,然后检查间隔是否为 2 月 29 日。有没有办法计算任何特定的时间间隔是否有特定的日期和发生次数,如果时间间隔跨越多年。

4

4 回答 4

2

以下 Java 风格的伪代码应该可以工作。如果您愿意,它还允许您添加其他过滤器:

int daysExcludingLeapYearDay(Date start, Date end)
{
    if(end.isBefore(start))
    {
        return filterOutLeapYearDays(daysBetween(end, start)).size();
    }

    return filterOutLeapYearDays(daysBetween(start, end)).size();
}

List<Date> filterOutLeapYearDays(List<Date> days)
{
    List<Date> daysExcludingLeapYearDays = 
             days
             .filter(d -> !isFeb29(d))
             .toList());

    return daysExcludingLeapYearDays;
}

List<Date> daysBetween(Date start, Date end) 
{
    List<Date> days = new List();

    for (Date day = start; day.isBefore(end); day = day.plusOneDay()) 
    {
        days.add(day);
    }

    return days
}

boolean isFeb29(Date date) 
{
    return date.month == FEBRUARY && date.day == 29;
}
于 2016-02-27T10:27:54.330 回答
1

但它不是由 2 月 29 日引起的,它是正确的。

如果您比较 2012 年 3 月 1 日和 2012 年 2 月 28 日将返回 1 天,而 29th 将返回 2 天。这两个日期之间的差异是一天。

要返回 0 天,您应该比较两个相同的日期,例如 2012 年 3 月 1 日和 2012 年 3 月 1 日。

我想你误会了^^。

于 2012-09-18T11:18:40.827 回答
0

我听说过 360 天年,但这是我第一次遇到 365 天年。

最好的办法是以天为单位计算日期之间的差异,并减去您遇到的所有 2 月 29 日。

这意味着您需要一个例程来遍历您的日期范围并返回您遇到的 2 月 29 日的数量。

我不知道如何在 JodaTime 中做到这一点,但基本算法是

  • 将开始日期转换为自 1970 年 1 月 1 日以来的天数。
  • 将结束日期转换为自 1970 年 1 月 1 日以来的天数。
  • 一次从开始日循环到结束日。
  • 将循环日转换回日期。
  • 如果日期是 2 月 29 日,计数器加 1
  • 完成循环后,返回计数器。
于 2012-09-18T13:28:23.480 回答
0

使用 javascript,您可以按如下方式实现它,其中startDateendDate是 javascriptDate对象。

function calculateDays(startDate,endDate){
    var oneDay = 86400000; //ms per day
    var difference = Math.ceil((endDate.getTime() - startDate.getTime()) / oneDay); 
    var totFeb29s = findTotalFeb29s(startDate,endDate);
    return  parseInt(difference)+parseInt(1)-parseInt(totFeb29s);    
}    
function findTotalFeb29s(startDate,endDate){
    var totalFeb29s = 0;
    var startYear = startDate.getFullYear();
    var endYear = endDate.getFullYear();
    for(var year=startYear;year<=endYear;year++){
        var dt = new Date(year, 1, 29);
        var isLeap = dt.getMonth() == 1;
        if(isLeap==true && startDate<=dt && dt<=endDate){
           totalFeb29s = parseInt(totalFeb29s)+parseInt(1);
        }
    }
    return totalFeb29s;
}    
于 2013-08-28T22:32:17.210 回答