You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 14:47:36