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

基于历史时段记录计算用户总可用时长(分钟)的技术实现请求

用户总可用时长计算实现方案

1. 数据预处理

  • 先修正原始历史记录的JSON语法错误,转换为结构化数组,确保每个时间节点(注册/更新日期)对应正确的可用时段配置:
{
  "2022-12-20": [
    {
      "dayNumber": 2,
      "startHours": "08:00",
      "endHours": "10:00"
    },
    {
      "dayNumber": 3,
      "startHours": "11:00",
      "endHours": "16:00"
    }
  ],
  "2022-12-28": [
    {
      "dayNumber": 2,
      "startHours": "08:00",
      "endHours": "10:00"
    },
    {
      "dayNumber": 3,
      "startHours": "11:00",
      "endHours": "16:00"
    }
  ],
  "2023-01-01": [
    {
      "dayNumber": 5,
      "startHours": "05:00",
      "endHours": "10:00"
    },
    {
      "dayNumber": 7,
      "startHours": "19:00",
      "endHours": "22:00"
    }
  ]
}
  • 提取所有时间节点并按升序排序,补充当前时间作为最后一个节点,形成完整的区间划分依据:["2022-12-20", "2022-12-28", "2023-01-01", 当前时间]

2. 核心计算逻辑

2.1 单时段时长转换函数

将单个可用时段的起止时间转换为分钟差值:

function calculateSingleSlotMinutes($startHours, $endHours) {
    list($startH, $startM) = explode(':', $startHours);
    list($endH, $endM) = explode(':', $endHours);
    return ($endH * 60 + $endM) - ($startH * 60 + $startM);
}

2.2 单配置每周总时长计算

基于某一时间节点的可用配置,计算该规则下每周的总可用分钟数:

function calculateWeeklyTotalMinutes($slots) {
    $total = 0;
    foreach ($slots as $slot) {
        $total += calculateSingleSlotMinutes($slot['startHours'], $slot['endHours']);
    }
    return $total;
}

2.3 分区间累加总时长

遍历每个时间区间,分别计算完整周数的时长和剩余天数的零散时长:

// 初始化排序后的时间节点数组
$timePoints = array_keys($availabilityData);
sort($timePoints);
// 添加当前时间到节点列表末尾
$now = Carbon::now()->toDateString();
$timePoints[] = $now;

$totalAvailableMinutes = 0;

for ($i = 0; $i < count($timePoints) - 1; $i++) {
    $startDate = Carbon::parse($timePoints[$i]);
    $endDate = Carbon::parse($timePoints[$i+1]);
    
    // 获取当前区间对应的可用时段配置
    $currentSlots = $availabilityData[$timePoints[$i]];
    $weeklyMinutes = calculateWeeklyTotalMinutes($currentSlots);
    
    // 计算区间内的完整周数和剩余天数
    $fullWeeks = $startDate->diffInWeeks($endDate, false);
    $remainingDays = $startDate->copy()->addWeeks($fullWeeks)->diffInDays($endDate, false);
    
    // 累加完整周的时长
    $totalAvailableMinutes += $fullWeeks * $weeklyMinutes;
    
    // 计算剩余天数的可用时长
    if ($remainingDays > 0) {
        $tempDate = $startDate->copy()->addWeeks($fullWeeks);
        for ($d = 0; $d < $remainingDays; $d++) {
            // 匹配当天的星期数(注意:Carbon的dayOfWeek为1=周一,7=周日,需与业务定义的dayNumber对齐)
            $dayNum = $tempDate->dayOfWeek;
            foreach ($currentSlots as $slot) {
                if ($slot['dayNumber'] == $dayNum) {
                    $totalAvailableMinutes += calculateSingleSlotMinutes($slot['startHours'], $slot['endHours']);
                    break;
                }
            }
            $tempDate->addDay();
        }
    }
}

3. 关键注意事项

  • 确保业务定义的dayNumber与Carbon的dayOfWeek匹配:若业务中dayNumber以1代表周日,需调整转换逻辑
  • 处理边界场景:比如注册日期与首次更新日期为同一天时,该区间时长直接记为0
  • 剩余天数跨周时,需准确遍历每一天对应的星期数,避免漏算或重复计算

内容的提问来源于stack exchange,提问作者DEVLOGIN

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 14:40:07