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

员工考勤数据处理需求:跨零点下班记录归属上班日期

解决跨零点下班考勤记录归属错误问题

问题场景:
员工跨00:00打卡下班时,考勤记录会被归属到次日,导致工时统计困难。比如id_employee=27的员工在2023-08-02 00:12:06的下班记录,目前被分到8月2日的考勤记录中,实际需要将这条记录归属到8月1日,同时保留原时间00:12:06,以便正常统计工时。

当前使用的cron job处理脚本:

$dataFingerprint = CheckInOut::all();

foreach ($dataFingerprint as $value) {
    $id_employee = $value->userid;
    $date = Carbon::parse($value->checktime)->day;
    $month = Carbon::parse($value->checktime)->month;
    $year = Carbon::parse($value->checktime)->year;


    $cekData = PresenceRecord::where('id_employee', $id_employee)
              ->where('date', $date)
              ->where('period_month', $month)
              ->where('period_year', $year)
              ->first();

    if($cekData){
        $result = $cekData;
    } else {
        $result = new PresenceRecord();
    }

    $result->id_employee = $id_employee;
    $result->date = $date;
    $result->period_month = $month;
    $result->period_year = $year;
    if($value->checktype == "in"){
        $result->time_in = date("H:i:s",strtotime($value->checktime));
    } else if($value->checktype == "out") {
        $result->time_out = date("H:i:s",strtotime($value->checktime));
    }
    $result->save();
}

修改后的脚本

核心思路:对下班记录判断打卡时间是否在深夜时段(比如00:00-06:00,可根据实际情况调整),如果是,则将归属日期往前推一天,同时保留原时间不变。

$dataFingerprint = CheckInOut::all();

foreach ($dataFingerprint as $value) {
    $id_employee = $value->userid;
    $checkTime = Carbon::parse($value->checktime);
    
    // 初始化归属日期为打卡当天
    $targetDate = $checkTime->copy();
    
    // 判断:如果是下班记录且打卡时间在00:00-06:00之间,归属日期改为前一天
    if ($value->checktype == "out" && $checkTime->hour < 6) {
        $targetDate->subDay();
    }
    
    $date = $targetDate->day;
    $month = $targetDate->month;
    $year = $targetDate->year;

    $cekData = PresenceRecord::where('id_employee', $id_employee)
              ->where('date', $date)
              ->where('period_month', $month)
              ->where('period_year', $year)
              ->first();

    $result = $cekData ?? new PresenceRecord();

    $result->id_employee = $id_employee;
    $result->date = $date;
    $result->period_month = $month;
    $result->period_year = $year;
    
    if ($value->checktype == "in") {
        $result->time_in = $checkTime->format('H:i:s');
    } elseif ($value->checktype == "out") {
        $result->time_out = $checkTime->format('H:i:s');
    }
    
    $result->save();
}

关键改动说明

  1. 统一时间解析:只解析一次checktime为Carbon实例,避免重复解析提升效率
  2. 深夜下班归属调整:对下班记录增加时段判断,将00:00-06:00的下班记录归属到前一天
  3. 简化代码逻辑:用??运算符替代原有的if-else判断,简化实例获取逻辑
  4. 统一时间格式化:用Carbon的format方法替代date函数,保持代码风格一致

内容的提问来源于stack exchange,提问作者Angga Tusan Adji

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 19:44:57