Google 日历 API 算法查找给定日期的开放时间段
Google Calendar API algorithm to find open time slots for a given day
我正在尝试利用 Google 日历(和 Google 日历 API)进行简单的日程安排。我正在使用 PHP、MySQL 和 google-api-php-客户端。我正在寻找一种算法或伪代码来查找开放时间段。
我的日历有繁忙时间的活动,例如营业结束时和当前约会。我能够通过两个函数(事件:列表和空闲忙:查询)检索事件开始和结束时间。这是今天的事件列表示例,开始时间为 2016-02-19T01:00:00-07:00,结束时间为 2016-02-19T23:00:00-07:00(当天的所有内容) .
从 12:00am 到 11:00am
停业
开始:“2016-02-19T00:00:00-07:00”
结束:“2016-02-19T11:00:00-07:00”
从1:30pm到2:30pm
的约会
开始:“2016-02-19T13:30:00-07:00”
结束:“2016-02-19T14:30:00-07:00”
从5:00pm到7:00pm
的约会
开始:“2016-02-19T17:00:00-07:00”
结束:“2016-02-19T19:00:00-07:00”
从9:00pm到11:00pm
的约会
开始:“2016-02-19T21:00:00-07:00”
结束:“2016-02-19T23:00:00-07:00”
我基于此示例事件集的开放时间段是:11:00am 到 1:30pm、2:30pm 到 5:00pm、7:00pm 到 9:00pm 和 11:00pm 到 12:00am.
- 如何以编程方式找到这组时间?
理想情况下,我希望通过一次 API 调用和 interpret/manipulate 获得给定日期的完整事件列表,而不是使用特定的开始和结束时间进行多次调用,这会给我正在寻找的信息,但效率很低。
- 找到集合后,如何以 30 分钟为增量显示结果,即可用预约开始时间为:
11:00,11:30,12:00,12:30,1:00,2:30,3:00,3:30,4:00,4:30,9:00,9 :30,10:00,10:30,11:00,11:30
我很难集中精力处理 dates/time 数据集。
这是 Google Calendar 的图像。相关日期是 2/19/2016
谢谢你。本次讨论的任何来源都将发布以供参考。
我会将日期转换为 unix 时间戳并计算开始日期和结束日期之间的差异。这就是我将如何完成你问题的第一部分:
$events = array(
array(
'start' => '2016-02-19T00:00:00-07:00',
'end' => '2016-02-19T11:00:00-07:00'
),
array(
'start' => '2016-02-19T13:30:00-07:00',
'end' => '2016-02-19T14:30:00-07:00'
),
array(
'start' => '2016-02-19T17:00:00-07:00',
'end' => '2016-02-19T19:00:00-07:00'
),
array(
'start' => '2016-02-19T21:00:00-07:00',
'end' => '2016-02-19T23:00:00-07:00'
)
);
$free_time_slots = array();
$count = count($events)-1;
$i = 0;
foreach($events as $event) {
if ($i < $count) {
$free_time = strtotime($events[$i+1]['start']) - strtotime($event['end']);
$free_time_slots[] = array(
'start' => date("F j, Y, g:i a", strtotime($event['end'])),
'end' => date("F j, Y, g:i a", strtotime($events[$i+1]['start'])),
'minutes' => $free_time / 60
);
$i++;
}
}
echo '<pre>';
print_r($free_time_slots);
这将导致:
Array
(
[0] => Array
(
[start] => February 19, 2016, 11:00 am
[end] => February 19, 2016, 1:30 pm
[minutes] => 150
)
[1] => Array
(
[start] => February 19, 2016, 2:30 pm
[end] => February 19, 2016, 5:00 pm
[minutes] => 150
)
[2] => Array
(
[start] => February 19, 2016, 7:00 pm
[end] => February 19, 2016, 9:00 pm
[minutes] => 120
)
)
这应该可以完成工作。您可以在要搜索的时间范围内循环遍历每个约会时段。在该循环内,您可以检查每个当前约会以查看是否存在冲突。此代码将在每次迭代后回显打开的约会,但您可能希望将它们放入一个数组中,以便在需要的任何地方使用它们。
// Set timezone = UTC for consistency
date_default_timezone_set("UTC");
// Range to search for open times in.
$start_time = strtotime("2016-02-19T00:00:00-07:00");
$end_time = strtotime("2016-02-19T23:59:59-07:00");
// Test data
$events = array(
"event_1" => array(
"start" => "2016-02-19T00:00:00-07:00",
"end" => "2016-02-19T11:00:00-07:00"
),
"event_2" => array(
"start" => "2016-02-19T13:30:00-07:00",
"end" => "2016-02-19T14:30:00-07:00"
),
"event_3" => array(
"start" => "2016-02-19T17:00:00-07:00",
"end" => "2016-02-19T19:00:00-07:00"
),
"event_4" => array(
"start" => "2016-02-19T21:00:00-07:00",
"end" => "2016-02-19T23:00:00-07:00"
),
);
// Kick off first appt time at beginning of the day.
$appt_start_time = $start_time;
// Loop through each appt slot in the search range.
while ($appt_start_time < $end_time) {
// Add 29:59 to the appt start time so we know where the appt will end.
$appt_end_time = ($appt_start_time + 1799);
// For each appt slot, loop through the current appts to see if it falls
// in a slot that is already taken.
$slot_available = true;
foreach ($events as $event => $times) {
$this_start = strtotime($times['start']);
$this_end = strtotime($times['end']);
// If the appt start time or appt end time falls on a current appt, slot is taken.
if (($appt_start_time >= $this_start && $appt_start_time < $this_end) ||
($appt_end_time >= $this_start && $appt_end_time < $this_end)) {
$slot_available = false;
break; // No need to continue if it's taken.
}
}
// If we made it through all appts and the slot is still available, it's an open slot.
if ($slot_available) {
$date = new DateTime();
$date->setTimestamp($appt_start_time);
$date->setTimezone(new DateTimeZone("America/Denver"));
echo "Open appt at: ". $date->format("Y-m-d h:i:s-e") ."<br />";
}
// + 30 minutes
$appt_start_time += (60 * 30);
}
这导致:
Open appt at: 2016-02-19 11:00:00-America/Denver
Open appt at: 2016-02-19 11:30:00-America/Denver
Open appt at: 2016-02-19 12:00:00-America/Denver
Open appt at: 2016-02-19 12:30:00-America/Denver
Open appt at: 2016-02-19 01:00:00-America/Denver
Open appt at: 2016-02-19 02:30:00-America/Denver
Open appt at: 2016-02-19 03:00:00-America/Denver
Open appt at: 2016-02-19 03:30:00-America/Denver
Open appt at: 2016-02-19 04:00:00-America/Denver
Open appt at: 2016-02-19 04:30:00-America/Denver
Open appt at: 2016-02-19 07:00:00-America/Denver
Open appt at: 2016-02-19 07:30:00-America/Denver
Open appt at: 2016-02-19 08:00:00-America/Denver
Open appt at: 2016-02-19 08:30:00-America/Denver
Open appt at: 2016-02-19 11:00:00-America/Denver
Open appt at: 2016-02-19 11:30:00-America/Denver
我正在尝试利用 Google 日历(和 Google 日历 API)进行简单的日程安排。我正在使用 PHP、MySQL 和 google-api-php-客户端。我正在寻找一种算法或伪代码来查找开放时间段。
我的日历有繁忙时间的活动,例如营业结束时和当前约会。我能够通过两个函数(事件:列表和空闲忙:查询)检索事件开始和结束时间。这是今天的事件列表示例,开始时间为 2016-02-19T01:00:00-07:00,结束时间为 2016-02-19T23:00:00-07:00(当天的所有内容) .
从 12:00am 到 11:00am
停业
开始:“2016-02-19T00:00:00-07:00”
结束:“2016-02-19T11:00:00-07:00”
从1:30pm到2:30pm
的约会
开始:“2016-02-19T13:30:00-07:00”
结束:“2016-02-19T14:30:00-07:00”
从5:00pm到7:00pm
的约会
开始:“2016-02-19T17:00:00-07:00”
结束:“2016-02-19T19:00:00-07:00”
从9:00pm到11:00pm
的约会
开始:“2016-02-19T21:00:00-07:00”
结束:“2016-02-19T23:00:00-07:00”
我基于此示例事件集的开放时间段是:11:00am 到 1:30pm、2:30pm 到 5:00pm、7:00pm 到 9:00pm 和 11:00pm 到 12:00am.
- 如何以编程方式找到这组时间?
理想情况下,我希望通过一次 API 调用和 interpret/manipulate 获得给定日期的完整事件列表,而不是使用特定的开始和结束时间进行多次调用,这会给我正在寻找的信息,但效率很低。
- 找到集合后,如何以 30 分钟为增量显示结果,即可用预约开始时间为:
11:00,11:30,12:00,12:30,1:00,2:30,3:00,3:30,4:00,4:30,9:00,9 :30,10:00,10:30,11:00,11:30
我很难集中精力处理 dates/time 数据集。
这是 Google Calendar 的图像。相关日期是 2/19/2016
谢谢你。本次讨论的任何来源都将发布以供参考。
我会将日期转换为 unix 时间戳并计算开始日期和结束日期之间的差异。这就是我将如何完成你问题的第一部分:
$events = array(
array(
'start' => '2016-02-19T00:00:00-07:00',
'end' => '2016-02-19T11:00:00-07:00'
),
array(
'start' => '2016-02-19T13:30:00-07:00',
'end' => '2016-02-19T14:30:00-07:00'
),
array(
'start' => '2016-02-19T17:00:00-07:00',
'end' => '2016-02-19T19:00:00-07:00'
),
array(
'start' => '2016-02-19T21:00:00-07:00',
'end' => '2016-02-19T23:00:00-07:00'
)
);
$free_time_slots = array();
$count = count($events)-1;
$i = 0;
foreach($events as $event) {
if ($i < $count) {
$free_time = strtotime($events[$i+1]['start']) - strtotime($event['end']);
$free_time_slots[] = array(
'start' => date("F j, Y, g:i a", strtotime($event['end'])),
'end' => date("F j, Y, g:i a", strtotime($events[$i+1]['start'])),
'minutes' => $free_time / 60
);
$i++;
}
}
echo '<pre>';
print_r($free_time_slots);
这将导致:
Array
(
[0] => Array
(
[start] => February 19, 2016, 11:00 am
[end] => February 19, 2016, 1:30 pm
[minutes] => 150
)
[1] => Array
(
[start] => February 19, 2016, 2:30 pm
[end] => February 19, 2016, 5:00 pm
[minutes] => 150
)
[2] => Array
(
[start] => February 19, 2016, 7:00 pm
[end] => February 19, 2016, 9:00 pm
[minutes] => 120
)
)
这应该可以完成工作。您可以在要搜索的时间范围内循环遍历每个约会时段。在该循环内,您可以检查每个当前约会以查看是否存在冲突。此代码将在每次迭代后回显打开的约会,但您可能希望将它们放入一个数组中,以便在需要的任何地方使用它们。
// Set timezone = UTC for consistency
date_default_timezone_set("UTC");
// Range to search for open times in.
$start_time = strtotime("2016-02-19T00:00:00-07:00");
$end_time = strtotime("2016-02-19T23:59:59-07:00");
// Test data
$events = array(
"event_1" => array(
"start" => "2016-02-19T00:00:00-07:00",
"end" => "2016-02-19T11:00:00-07:00"
),
"event_2" => array(
"start" => "2016-02-19T13:30:00-07:00",
"end" => "2016-02-19T14:30:00-07:00"
),
"event_3" => array(
"start" => "2016-02-19T17:00:00-07:00",
"end" => "2016-02-19T19:00:00-07:00"
),
"event_4" => array(
"start" => "2016-02-19T21:00:00-07:00",
"end" => "2016-02-19T23:00:00-07:00"
),
);
// Kick off first appt time at beginning of the day.
$appt_start_time = $start_time;
// Loop through each appt slot in the search range.
while ($appt_start_time < $end_time) {
// Add 29:59 to the appt start time so we know where the appt will end.
$appt_end_time = ($appt_start_time + 1799);
// For each appt slot, loop through the current appts to see if it falls
// in a slot that is already taken.
$slot_available = true;
foreach ($events as $event => $times) {
$this_start = strtotime($times['start']);
$this_end = strtotime($times['end']);
// If the appt start time or appt end time falls on a current appt, slot is taken.
if (($appt_start_time >= $this_start && $appt_start_time < $this_end) ||
($appt_end_time >= $this_start && $appt_end_time < $this_end)) {
$slot_available = false;
break; // No need to continue if it's taken.
}
}
// If we made it through all appts and the slot is still available, it's an open slot.
if ($slot_available) {
$date = new DateTime();
$date->setTimestamp($appt_start_time);
$date->setTimezone(new DateTimeZone("America/Denver"));
echo "Open appt at: ". $date->format("Y-m-d h:i:s-e") ."<br />";
}
// + 30 minutes
$appt_start_time += (60 * 30);
}
这导致:
Open appt at: 2016-02-19 11:00:00-America/Denver
Open appt at: 2016-02-19 11:30:00-America/Denver
Open appt at: 2016-02-19 12:00:00-America/Denver
Open appt at: 2016-02-19 12:30:00-America/Denver
Open appt at: 2016-02-19 01:00:00-America/Denver
Open appt at: 2016-02-19 02:30:00-America/Denver
Open appt at: 2016-02-19 03:00:00-America/Denver
Open appt at: 2016-02-19 03:30:00-America/Denver
Open appt at: 2016-02-19 04:00:00-America/Denver
Open appt at: 2016-02-19 04:30:00-America/Denver
Open appt at: 2016-02-19 07:00:00-America/Denver
Open appt at: 2016-02-19 07:30:00-America/Denver
Open appt at: 2016-02-19 08:00:00-America/Denver
Open appt at: 2016-02-19 08:30:00-America/Denver
Open appt at: 2016-02-19 11:00:00-America/Denver
Open appt at: 2016-02-19 11:30:00-America/Denver