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

如何从PHP数组中提取单日数据并计算当日工作时长

实现用户整月每日工作时长统计的方案

嘿,我看你已经有了遍历Excel数据的基础脚本,接下来咱们把它升级一下,实现按用户、按日期分组统计每日工作时长的功能,刚好满足你整月统计的需求~

第一步:按用户+日期分组记录

首先咱们需要把分散的记录归类,同一个用户同一天的所有打卡时间放在一起,这样后续计算时长才方便。这里用多维数组来分组,第一层是用户名,第二层是日期,对应的值是该用户当日的所有时间戳(时间戳计算时差更准确):

// 初始化分组数组
$userDailyRecords = [];

foreach($xlsArr as $row){ 
    $fullName = $row['first-name'] . ' ' . $row['last-name'];
    // 用DateTime处理时间,避免字符串操作的误差
    $datetime = new DateTime($row['time']);
    $dateOnly = $datetime->format('Y-m-d'); // 提取纯日期(比如2022-04-01)
    $timestamp = $datetime->getTimestamp(); // 转换为时间戳,方便后续计算

    // 构建分组结构
    if (!isset($userDailyRecords[$fullName])) {
        $userDailyRecords[$fullName] = [];
    }
    if (!isset($userDailyRecords[$fullName][$dateOnly])) {
        $userDailyRecords[$fullName][$dateOnly] = [];
    }
    $userDailyRecords[$fullName][$dateOnly][] = $timestamp;
}

第二步:计算每日工作时长

分组完成后,咱们就可以遍历每个用户的每日记录,计算工作时长了。这里默认取当日最早的打卡时间作为上班时间,最晚的作为下班时间,两者的差值就是当日工作时长;如果当天只有1条记录,会标记为打卡异常:

// 初始化结果数组,存储每个用户的每日工作时长
$userDailyWorkHours = [];

foreach ($userDailyRecords as $fullName => $dailyRecords) {
    $userDailyWorkHours[$fullName] = [];
    foreach ($dailyRecords as $date => $timestamps) {
        // 处理打卡记录不全的情况
        if (count($timestamps) < 2) {
            $userDailyWorkHours[$fullName][$date] = '打卡记录不全';
            continue;
        }
        // 排序时间戳,找到最早和最晚的打卡时间
        sort($timestamps);
        $firstTimestamp = reset($timestamps); // 最早的时间戳
        $lastTimestamp = end($timestamps); // 最晚的时间戳
        
        // 计算时长(转换为小时,保留两位小数)
        $durationSeconds = $lastTimestamp - $firstTimestamp;
        $workHours = round($durationSeconds / 3600, 2);
        
        $userDailyWorkHours[$fullName][$date] = "{$workHours}小时";
    }
}

第三步:输出统计结果

现在你可以按需输出结果了,比如查看指定用户(比如John Doe)的整月统计,或者遍历所有用户的数据:

// 输出指定用户的整月工作时长
$targetUser = 'John Doe';
if (isset($userDailyWorkHours[$targetUser])) {
    echo "<h3>{$targetUser} 整月工作时长统计</h3>";
    foreach ($userDailyWorkHours[$targetUser] as $date => $hours) {
        echo "- {$date}: {$hours}<br>";
    }
} else {
    echo "未找到用户 {$targetUser} 的记录";
}

// 或者输出所有用户的统计数据
foreach ($userDailyWorkHours as $fullName => $dailyHours) {
    echo "<h3>{$fullName} 整月工作时长统计</h3>";
    foreach ($dailyHours as $date => $hours) {
        echo "- {$date}: {$hours}<br>";
    }
}

一些额外说明

  • 用DateTime处理时间比直接切割字符串更可靠,能自动处理不同的时间格式(只要你的数据源格式是标准的)。
  • 如果你的打卡记录是严格的“上班-下班”成对出现,也可以调整逻辑,每两个时间一组计算时长再累加,这个可以根据你的实际数据结构调整。
  • 针对异常情况(比如单日只有1条记录),你可以根据业务需求改成默认0小时,或者其他标记方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 21:02:31