查找数据数组中的下一个可用时间段

时间:2016-08-17 14:22:47

标签: javascript php jquery

我有一个数组,里面有一个'events'数组,里面包含一系列事件。

$data = array(
'events'=> array(
    array(
    'title' => 't1',
    'start_time' => '12:00AM',
    'end_time' => '1:00AM',
    ),
        array(
    'title' => 't1',
    'start_time' => '1:00PM',
    'end_time' => '1:30PM',
    ),
        array(
    'title' => 't1',
    'start_time' => '1:30PM',
    'end_time' => '2:00PM',
    ),
        array(
    'title' => 't1',
    'start_time' => '3:15PM',
    'end_time' => '3:45PM',
    ),
        array(
    'title' => 't1',
    'start_time' => '3:45PM',
    'end_time' => '4:45PM',
    )
    )
);

根据当前时间,我正在尝试找到至少15分钟的下一个可用时段。所以说它当前下午1:15,下一个可用的时间段是下午2:00(基于提供的数据阵列)。这似乎很容易,但我很难过。

下面的代码是我所在的地方。如果在当前时间发生了一个事件,它将返回标题,但我不确定如何获得下一个没有被拍摄的时段。

$time = time();
$timePlus15 = time() + 60*15;

foreach ($events->events as $key => $event) {
    $start_time = strtotime($event->start_time);
    $end_time = strtotime($event->end_time);

        if (($time > $start_time && $timePlus15 < $end_time) || $time > $start_time && $time < $end_time || ($time < $start_time && $timePlus15 > $start_time && $timePlus15 < $end_time)) {
            echo $event->title;
    }
}

基本上,我想循环遍历数组。如果在当前时间有事件,请将时间增加15分钟并再次检查。如果有事件,请增加15分钟并再次检查,然后重复直到当时没有事件,然后返回该时间。

代码在php中,但我也接受javascript / jquery答案

**我的问题的解决方案如下**

this.setNextAvailableTime = function() {
    var requiredGap = 15 * 60 * 1000;
    var events = app.rooms.events[app.rooms.current_room].events;
    var prev = events[0];
    var firstGap = null;
    if (events.length === 1) {
        firstGap = prev.end_24time;
    } else {
        for (var i = 1; i < events.length; i += 1) {

            var current = events[i];

            var current_start = new Date();
            var prev_end = new Date();
            current_start.setHours(events[i].start_24time.substring(0,2),events[i].start_24time.substring(3,5), 0);
            prev_end.setHours(prev.end_24time.substring(0,2),prev.end_24time.substring(3,5), 0);

            var diff = current_start.getTime() - prev_end.getTime();

            if( diff >= requiredGap) {
                firstGap = prev.end_24time;
                break;
            }

            prev = current;
        }           
    }
    //do something with the firstGap time
    $('#start_time').val(firstGap);
};

3 个答案:

答案 0 :(得分:4)

可能更容易看出第一个事件的end与下一个事件的start 之间的区别是什么。这是javascript中的一个例子:

(请注意,迄今为止的字符串转换不是很稳固,只是一些测试数据)

var events = [{
  start: "2016-01-01T12:00",
  end: "2016-01-01T13:00"
}, {
  start: "2016-01-01T13:00",
  end: "2016-01-01T13:30"
}, {
  start: "2016-01-01T13:30",
  end: "2016-01-01T14:00"
}, {
  start: "2016-01-01T15:15",
  end: "2016-01-01T15:45"
}, {
  start: "2016-01-01T15:45",
  end: "2016-01-01T16:45"
}];

var dateEvents = events.map(function(event) {
  return {
    start: new Date(event.start),
    end: new Date(event.end)
  };
});

var requiredGap = 15 * 60 * 1000;
var prev = dateEvents[0];
var firstGap = null;

for (var i = 1; i < dateEvents.length; i += 1) {
  var current = dateEvents[i];
  var diff = current.start - prev.end;
  
  if (diff >= requiredGap) {
    firstGap = {
      start: prev.end,
      end: current.start
    };
    break;
  }
  
  prev = current;
}

if (firstGap != null) {
  console.log("First gap starts at: " + firstGap.start); 
} else {
  console.log("No gaps available");
}

答案 1 :(得分:1)

Javascript解决方案。在es6fiddle中运行: http://www.es6fiddle.net/irz39uss/

从字符串转换为分钟,反之亦然是大多数实际工作。之后,它只是创建一个数组,而不是事件所用的时间,表示事件之间可用的时间。我正在使用map稍微作弊的版本(作弊因为我转发引用一个元素,这不是一个真正的功能方法,但嘿,它是JS)。接下来,找到开始时间等于或等于当前时间的第一个,以及至少有15分钟可用的时间。

从概念上讲,简单地执行字符串到时间转换非常麻烦。这适用于午夜到午夜,而不是隔天。我使用了你难以处理的时间字符串而不是其他解决方案,这不是你发布的,所以考虑一个“接受”,因为它适用于你的实际输入;)

let eventsArr = [{title: 't1', start_time: '1:00PM', end_time: '1:30PM'},
                 {title: 't1', start_time: '1:30PM', end_time: '2:00PM'},
                 {title: 't1', start_time: '3:15PM', end_time: '3:45PM'}]

function strTimeToMins(c) {
    let rex = /([0-9]|0[0-9]|1[0-9]|2[0-3]):([0-5][0-9])([P,p,A,a])/
    let mat = c.match(rex)
    return 60*mat[1] + 1*mat[2] + ((mat[3] === 'P') ? 720 : 0)
}

function minsToStrTime(m) {
    let hr = Math.floor(m/60)
    let min = m%60
    let hours = (hr > 12 ? hr-12 : hr)
    return hours.toString() + ':' + ("00" + min).slice(-2) + (hr > 12 ? 'PM' : 'AM')
}

function objTimeToMins(o) {
    return { title: o.title,
             start_time: strTimeToMins(o.start_time),
             end_time: strTimeToMins(o.end_time) }
    }

let eventsArrMins = eventsArr.map(objTimeToMins)

let openTimes = eventsArrMins.map( (c,i,a) => ( (i+1 != a.length) ?
    { start: c.end_time, end: a[i+1].start_time } : {} ))

//let currTime = strTimeToMins ('1:15PM')
let currTime = Math.floor((new Date() - new Date().setHours(0,0,0,0))/1000)

let nextAvailable = openTimes.find(c => currTime <= c.start && c.end - c.start >= 15)

if (nextAvailable)
    console.log('Next available time is: ' + minsToStrTime(nextAvailable.start))
else
    console.log('There are no available times.')

答案 2 :(得分:0)

我将时间从上午/下午转换为24小时,软件找到最近的15分钟可用时间段。

&#13;
&#13;
// LIST
var t1 = [{
	start_time:"00:00", 
	end_time:"01:00" 
	},{ 
	start_time:"13:00", 
	end_time:"13:30" 
	},{
	start_time:"13:30", 
	end_time:"14:00" 
	},{
	start_time:"15:15", 
	end_time:"15:45" 
	},{ 
	start_time:"15:45", 
	end_time:"16:45" 
	},{ 
	start_time:"17:45", 
	end_time:"18:00" 
	},{ 
	start_time:"20:00", 
	end_time:"20:15" 
	},{ 
	start_time:"21:20", 
	end_time:"21:30" 
	}];

// VARIABLES
var gap = 15;
var currentTime = new Date();
var currentHour = currentTime.getHours();
var currentMinute = currentTime.getMinutes();
while (currentMinute % 5 !== 0)
{
	AddMinutes(1);
}
var lowestCounter = 0;
var tempStart =t1[lowestCounter].start_time;
var tempEnd = t1[lowestCounter].end_time;
var tempSlotStart = FormattedTime(currentHour) + ":" + FormattedTime(currentMinute);
var tempSlotEnd = TimeInMinutes(currentHour, currentMinute) + gap;
tempSlotEnd = MinutesInTime(tempSlotEnd);


// 1 - START - Skip the past Events
while (tempStart <= tempSlotStart && tempEnd <= tempSlotStart && lowestCounter < t1.length){
	lowestCounter++;	
	if (lowestCounter < t1.length){
		tempStart =t1[lowestCounter].start_time;
		tempEnd = t1[lowestCounter].end_time;
	}
}
// 1 - END


// 2 - START - Check for the first available gap
if (lowestCounter < t1.length){
	tempStart =t1[lowestCounter].start_time;
	tempEnd = t1[lowestCounter].end_time;
 	lowestCounter--;
}

while ((tempStart < tempSlotStart && tempEnd > tempSlotStart) || (tempStart < tempSlotEnd && tempEnd > tempSlotEnd) && lowestCounter < t1.length){
	lowestCounter++;
	if (lowestCounter < t1.length){
		tempStart =t1[lowestCounter].start_time;
		tempEnd = t1[lowestCounter].end_time;
    tempSlotStart = tempEnd;
    tempSlotEnd = TimeInMinutes(Number(tempSlotStart.split(":")[0]),Number(tempSlotStart.split(":")[1]));
    tempSlotEnd += gap;
    tempSlotEnd = MinutesInTime(tempSlotEnd);
  }
}
// 2 - END


// 3 - START - Print
console.log("First Available Schedule: " + tempSlotStart + " -> " + tempSlotEnd);
// 3 - END


// ASSETS - START
function AddMinutes(x){
  currentMinute += x;
  if (currentMinute >= 60){
  	currentMinute %= 60;
    currentHour++;
  }
  if (currentHour >= 24){
  	currentHour %= 24;
  }
}

function TimeInMinutes(hours,minutes){
	return hours * 60 + minutes;
}

function MinutesInTime(minutes){
	return FormattedTime(Math.floor(minutes/60) % 24) + ":" + FormattedTime(minutes%60);
}

function FormattedTime(x){
	if (x < 10){
  	return "0" + x;
  }
  return x;
}
// ASSETS - END
&#13;
&#13;
&#13;