【问题标题】:How to calculate free available time based on array values如何根据数组值计算空闲可用时间
【发布时间】:2013-10-10 04:03:23
【问题描述】:

假设我有一个如下所示的数组:

{
    meeting: 'one',
    start_time: "07:15:00",
    end_time: "08:15:00"
},
{
    meeting: 'two',
    start_time: "15:45:00",
    end_time: "18:15:00"
}

现在我想计算我从 00:00:00 到 24:00:00 的所有空闲时间。

例如,新数组将如下所示:

{
    meeting: 'free time',
    start_time: "00:00:00",
    end_time: "07:14:00"
},
{
    meeting: 'one',
    start_time: "07:15:00",
    end_time: "08:15:00"
},
{
    meeting: 'free time',
    start_time: "08:16:00",
    end_time: "15:44:00"
},
{
    meeting: 'two',
    start_time: "15:45:00",
    end_time: "18:15:00"
}

关于如何在没有插件的情况下完成此操作的任何建议?

【问题讨论】:

  • 我尝试将时间转换为毫秒,然后循环并从我的开始结束时间中减去,但这给了我一个总的空闲时间。老实说,我不确定到目前为止最好的方法是什么......:/
  • @Darkagelink 嘿,我更新了我的答案。现在完美运行。

标签: javascript jquery


【解决方案1】:

This is what I'll do:

function meeting(meeting, time1, time2) {
    this.meeting = meeting;
    this.start_time = time1;
    this.end_time = time2;
}


meeting.prototype.convert = function (a) {
    var b = this[a + '_time'];
    var start = b.slice(0, 3);
    var min = parseInt(b.slice(3, 5));
    min = a == "start" ? min - 1 : min + 1;
    min = min < 10 ? "0" + min : min;
    var ending = b.slice(5, 8);

    return start + min + ending

}

Array.prototype.getFreeTime = function () {
    var l = this.length,
        withFreeTime = [],
        i = 0;
    while (i < l) {

        var s = this[i - 1] ? this[i - 1].convert('end') : "00:00:00";
        withFreeTime.push(new meeting('freetime', s, this[i].convert('start')));
        withFreeTime.push(this[i]);
        i++;
    }

    //to add the freetime from "18:16:00" to  "23:59:00":
    withFreeTime.push(new meeting('freetime', this[i-1].convert('end'),'23:59:00'));

    return withFreeTime;
}

var meetings = [];
meetings[0] = new meeting('meeting1', "07:15:00", "08:15:00");
meetings[1] = new meeting('meeting2', "15:45:00", "18:15:00");
meetings = meetings.getFreeTime();
console.log(JSON.stringify(meetings));

consloe.log:

[{"meeting":"freetime","start_time":"00:00:00","end_time":"07:14:00"},
{"meeting":"meeting1","start_time":"07:15:00","end_time":"08:15:00"},
{"meeting":"freetime","start_time":"08:16:00","end_time":"15:44:00"},
{"meeting":"meeting2","start_time":"15:45:00","end_time":"18:15:00"},
{"meeting":"freetime","start_time":"18:16:00","end_time":"23:59:00"}]

【讨论】:

  • 一个问题我怎样才能从为“18:16 到 23:00”设置一个数组作为空闲时间?
  • @Darkagelink 只需在return withFreeTime; 前面添加withFreeTime.push(new meeting('freetime', this[i-1].convert('end'),'23:59:00'));(我已经更新了我的答案。)
  • 我只是有点困惑抱歉 - 为什么需要meetings[0] 而不是实际会议的数组...
  • meetings[0] 是数组的第一个元素。 new meeting('meeting1', "07:15:00", "08:15:00") 是一种创建对象{"meeting":"freetime","start_time":"00:00:00","end_time":"07:14:00"} 的方法。通过这种方式创建对象,我们可以使用meeting.prototype
【解决方案2】:

您需要在跟踪时间的同时遍历数组。 jsFiddle

function subtractMinute(time){
  var h = +time.substr(0, 2);
  var m = +time.substr(3, 2);

  if(m > 0){
    m -= 1;
  }else{
    if(h > 0){
      h -= 1;
    }else{
      return false;
    }
    m = 59;
  }

  if(h < 10)
    h = '0'+h;

  if(m < 10)
    m = '0'+m;

  return h+':'+m+':00';
}

function addMinute(time){
  var h = +time.substr(0, 2);
  var m = +time.substr(3, 2);

  if(m < 59){
    m += 1;
  }else{
    if(h < 22){
      h += 1;
    }else{
      return false;
    }
    m = 0;
  }

  if(h < 10)
    h = '0'+h;

  if(m < 10)
    m = '0'+m;

  return h+':'+m+':00';
}

//If meetings is already sorted by time
//you can skip this next bit of code
meetings.sort(function(a, b){
  return a.start_time > b.start_time? 1: -1;
});

var schedule = [];
var start_time = '00:00:00';
var end_time = '23:59:00';
for(var i=0, l=meetings.length; i<l; i++){
  end_time = subtractMinute(meetings[i].start_time);

  if(i)
    start_time = addMinute(meetings[i-1].end_time);

  if((end_time && !i) || (end_time && i && meetings[i-1].end_time < meetings[i].start_time))
    schedule.push({meeting: 'free time', start_time: start_time, end_time: end_time});

  schedule.push(meetings[i]);

  if(i+1 === l){
    start_time = addMinute(meetings[i].end_time);

    if(start_time)
        schedule.push({meeting: 'free time', start_time: start_time, end_time: '23:59:00'});
  }
}

console.log(schedule);

【讨论】:

    【解决方案3】:

    只是一个简单的例子

    var schedule = [{
        meeting: 'free time',
        start_time: "00:00:00",
        end_time: "07:14:00"
    },
    {
        meeting: 'one',
        start_time: "07:15:00",
        end_time: "08:15:00"
    },
    {
        meeting: 'free time',
        start_time: "08:16:00",
        end_time: "15:44:00"
    },
    {
        meeting: 'two',
        start_time: "15:45:00",
        end_time: "18:15:00"
    }]
    
    var st,
        se,
        fh, fm, fs,
        ft = 0;
    
    for (var i = 0; i < schedule.length; i++) {
    
        var s = schedule[i];
    
        if (s['meeting'] === 'free time') {
    
            st = s['start_time'].replace(/(\d+):(\d+):(\d+)/, function(t,h,m,s) {
              return (h * 3600) + (m * 60) + (+s);  
              // s is a string, +s converts it to an integer
    
            })            
            et = s['end_time'].replace(/(\d+):(\d+):(\d+)/, function(t,h,m,s) {
              return (h * 3600) + (m * 60) + (+s);         
            })         
    
            /* your free time in seconds for this slot */
            ft += (et-st);
        }
    }
    
    fh = ~~(ft / 3600);
    fm = ~~((ft - (fh * 3600)) / 60);
    fs = ft - (fh * 3600) - (fm * 60)
    
    console.log("you have %s:%s:%s free time", fh, fm, fs);
    // you have 14:42:0 free time
    

    【讨论】:

    • 我明白了,但是在您的示例中,您已经知道空闲时间。这就是我遇到麻烦的地方......我正在尝试找出将空闲时间添加到阵列的最佳方法。
    【解决方案4】:

    这是一种可能的解决方案 (JSFiddle here):

    var time = [{
        meeting: 'one',
        start_time: "07:15:00",
        end_time: "08:15:00"
    }, {
        meeting: 'two',
        start_time: "15:45:00",
        end_time: "18:15:00"
    }];
    
    // out contains the result
    // timeline is a list of minutes containing some event
    var out = [], timeline = [];
    
    // Add free time after the last meeting:
    // timeline[23*60] = undefined;
    
    // fill up the timeline
    for (var m = 0, current = 0; m < 24 * 60 && current < time.length; m += 1) {
        var start = str_as_min(time[current].start_time);
        var end = str_as_min(time[current].end_time);
    
        if (m >= start) {
            if (m <= end) {
                timeline[m] = time[current].meeting;
            } else {
                current += 1;
            }
        }
    }
    
    // fill up the out
    for (var m = 0, last = null; m < timeline.length; m += 1) {
        var current = timeline[m];
    
        if (current !== last) {
            if (out.length > 0) {
                out[out.length-1].end_time = min_as_str(m-1);
            }
    
            out.push({
                start_time: min_as_str(m),
                meeting: timeline[m] === undefined ? 'free_time' : timeline[m]
            });
        }
    
        if (m === timeline.length - 1) {
            out[out.length-1].end_time = min_as_str(m);
        }
    
        last = current;
    }
    
    console.log(JSON.stringify(out));
    
    // helper functions
    function min_as_str (min) {
        return Math.floor(min / 60) + ':' + (min % 60);
    }
    
    function str_as_min (str) {
        var m = str.match(/^(\d\d):(\d\d)/);
        return 60 * parseInt(m[1], 10) + parseInt(m[2], 10);
    }
    

    与您建议的示例输出数组的唯一区别是时间格式(即7:15 而不是07:15 - 您可以轻松解决此问题)。

    【讨论】:

    • 一个问题我怎样才能从为“18:15 到 23:00”设置一个数组作为空闲时间?
    • @Darkagelink - 只需使用 timeline[23*60] = undefined; - 我已将其放在示例中(已注释掉)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-25
    相关资源
    最近更新 更多