查找日期范围内的可用天数

时间:2016-04-16 21:26:11

标签: javascript algorithm date

假设有一个系统显示事件的日期可用性。我们有一个主要的日期范围,所有活动都在这里。事件也可以是日期范围。

示例:

[Date X]========================================[Date Y]
        [A]=====[A]        [B]=====[B][C]=====[C]
        [ Event A ][ Open ][ Event B ][ Event C ]

日期X和日期Y是事件发生的主要日期范围。 A,B和C是已安排的事件。

如何有效检索开放日期范围?

示例2:

var rangeStart = new Date("04-01-2016");
var rangeEnd = new Date("04-31-2016");

var eventAStart = new Date("04-01-2016");
var eventAEnd = new Date("04-06-2016");

var eventBStart = new Date("04-15-2016");
var eventBEnd = new Date("04-30-2016");

我需要返回类似的内容:

var availableRangeStart = "04-07-2015";
var availableRangeEnd = "04-14-2016";

因为这些是主要范围内的日期与“事件”范围不重叠。

准确地说我要做的事情:

我的应用程序是一个旅行计划器,用户设置旅行的日期,然后为该旅行添加具有自己日期的不同目的地。 (用户将于4月1日至4月30日前往欧洲旅行,他们将于4月1日至4月6日在巴黎,然后他们将于4月15日至4月30日在伦敦)。但是用户从4月7日到4月14日没有计划任何事情。我正在尝试返回这些日期,以便在他们添加新目的地时,日期已预先填写。

2 个答案:

答案 0 :(得分:2)

我只是给你一个算法,因为最终的实现取决于你的代码。

var aprilAvailableDays = [true, true, true, etc...] // a boolean for each day

aprilEvents.forEach(function (event) {
    for (var i = event.startDay; i <= event.endDay; i++) {
        aprilAvailableDays[i] = false;
    }
});

答案 1 :(得分:1)

这是一个从/到自由时段返回的解决方案:

// Helper function
function addDays(date, days) {
    return new Date(date.getTime() + days * 24*60*60*1000);
}

// Main function
function gaps(period, events) {
    events = events.slice(0).filter(function (a) {
        // Exclude events which are outside the main period
        return a.to >= period.from && a.from <= period.to;
    }).sort(function (a, b) {
        // Sort events by their starting date
        return a.from - b.from;
    });
    var result = events.reduce(function (result, curr) {
        if (curr.from - result.free > 0) {
            // gap found
            result.gaps.push({
                from: result.free, 
                to:   addDays(curr.from, -1)
            });
        }
        if (curr.to - result.free >= 0) {
            // first free day is after this event
            result.free = addDays(curr.to, 1)
        }
        return result;
    }, { gaps: [], free: period.from } );
    // Potentially add gap between last event end period-end
    if (period.to - result.free >= 0) {
        result.gaps.push({
            from: result.free,
            to:   period.to
        });
    }
    return result.gaps;
}


// Sample data:

var period = {
    from: new Date('2016-01-01'),
    to: new Date('2016-12-31')
};

var events = [
    { from: new Date('2016-02-01'), to: new Date('2016-02-29') },
    { from: new Date('2016-03-01'), to: new Date('2016-03-15') },
    { from: new Date('2016-04-16'), to: new Date('2016-04-30') },
];

// Call to function
var res = gaps(period, events);

// Output in snippet
document.write('<pre>' + JSON.stringify(res, null, 4));