从时间间隔中排除2月29日

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日。如果间隔跨越多年,有没有办法确定任何特定间隔是否有特定的日期和发生次数。


1
出于好奇,您为什么要排除2月29日? - Peter Lawrey
2
@peter-lawrey 我正在为一家保险公司编写代码,他们有一个政策,即如果保单被放弃或按比例计算,则不收取2月29日的保费。 - Hulk
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;
}

1

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

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

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

我认为您弄错了^^。


我在谈论两个日期之间完整的天数,不包括这两个日期本身。我会更新问题以获得更多的明确性。 - Hulk
1
嗯,我不知道是否可能,但如果您将年份更改为例如1900年,以便比较这两个日期呢? - Cechinel

0

使用JavaScript,您可以按以下方式实现,其中startDateendDate是JavaScript Date对象。

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

你为什么提供 JavaScript 的答案?问题并没有要求这个。 - Sean F

0

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

最好的方法是计算您的日期之间的天数差,并减去所有遇到的2月29日。

这意味着您需要一种例程,可以通过您的日期范围并返回您遇到的2月29日的数量来实现。

我不知道如何在JodaTime中实现此操作,但基本算法如下:

  • 将开始日期转换为自1970年1月1日以来的天数。
  • 将结束日期转换为自1970年1月1日以来的天数。
  • 从开始日期到结束日期一天一天地循环。
  • 将循环日转换回日期。
  • 如果日期是2月29日,则将计数器加1
  • 完成循环后,返回计数器。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接