Google Calendar FreeBusy API空闲时段分组与时段筛选问题
没问题,我来帮你搞定这几个需求,咱们一步步来:
1. 实现按日期分组 + 过滤指定时段(9:00-18:00)
首先咱们要调整代码逻辑,先把空闲时段按日期归类,同时在判断空闲时直接过滤掉非工作时间的槽。注意要基于你指定的Europe/Berlin时区来判断小时,避免时区偏差。
修改后的核心代码如下:
// ------------------ // 初始化配置和存储数组 // ------------------ $first_day_xp = strtotime('today GMT'); $last_day_xp = strtotime("2020-02-12T17:00:00.000Z"); $start_time = $first_day_xp; $end_time = $last_day_xp; $events = $busy_obj = array( ); $appt_start_time = $start_time; $appt_duration = 120; // 分钟 // 新增:按日期分组的空闲槽存储数组 $freeSlotsByDate = []; // 新增:定义工作时段(柏林时区9:00-18:00) $workStartHour = 9; $workEndHour = 18; // ------------------ // 循环遍历时段 // ------------------ while ($appt_start_time < $end_time) { $appt_end_time = ($appt_start_time + 1799); $slot_available = true; foreach ($events as $event => $times) { $this_start = strtotime($times['start']); $this_end = strtotime($times['end']); 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; } } if ($slot_available) { $date = new DateTime(); $date->setTimestamp($appt_start_time); $date->setTimezone(new DateTimeZone("Europe/Berlin")); // 过滤工作时段外的槽 $currentHour = (int)$date->format('H'); if ($currentHour >= $workStartHour && $currentHour < $workEndHour) { // 按日期作为key分组存储 $dateKey = $date->format('d-m-Y'); $slotInfo = [ 'start' => $date->format("h:i:s-e"), 'timestamp' => $appt_start_time ]; if (!isset($freeSlotsByDate[$dateKey])) { $freeSlotsByDate[$dateKey] = []; } $freeSlotsByDate[$dateKey][] = $slotInfo; } } $appt_start_time += (60 * $appt_duration); } // ------------------ // 按日期分组输出结果 // ------------------ foreach ($freeSlotsByDate as $date => $slots) { echo "<h3>日期: {$date}</h3>"; echo "<ul>"; foreach ($slots as $slot) { echo "<li>Créneau disponible: {$slot['start']}</li>"; } echo "</ul>"; }
这样输出就会自动按日期分组,并且只保留9:00-18:00之间的空闲槽啦。
2. 用JSON灵活处理数据
咱们已经把数据整理成了结构化的数组$freeSlotsByDate,转换成JSON只需要一行代码:
// 转换为格式化后的JSON字符串 $freeSlotsJson = json_encode($freeSlotsByDate, JSON_PRETTY_PRINT); // 如果是作为API接口返回,记得设置响应头 header('Content-Type: application/json'); echo $freeSlotsJson;
生成的JSON结构大概是这样的,非常方便后续前端或者其他系统解析使用:
{ "09-02-2020": [ { "start": "09:00:00-Europe/Berlin", "timestamp": 1581229200 }, { "start": "11:00:00-Europe/Berlin", "timestamp": 1581236400 } ], "10-02-2020": [ { "start": "09:00:00-Europe/Berlin", "timestamp": 1581315600 } ] }
额外小建议
- 可以把工作时段的起止小时做成可配置的变量,后期调整更方便
- 确保所有时间处理都统一使用
Europe/Berlin时区,避免出现时间偏差 - 如果
$events数据来自Google API,建议提前把事件时间转换为UTC再比较,减少时区转换的潜在问题
内容的提问来源于stack exchange,提问作者sterhamy
相关产品推荐
相关产品推荐

