从时间间隔排除2月29日

时间:2012-09-18 10:34:09

标签: java date jodatime

我想从两个日期之间没有完整日期的计算中排除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 个答案:

答案 0 :(得分:1)

但它不是由29日引起的,它是对的。

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

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

我认为你错了^^。

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

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

您最好的选择是计算日期之间的差异,并减去您遇到的所有2月29日。

这意味着您需要一个能够完成日期范围的例行程序并返回您遇到的2月29日的计数。

我不知道如何在JodaTime中执行此操作,但基本算法将是

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

答案 3 :(得分: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;
}