上篇文章中提到了将考勤时间进行装置《C# 将员工考勤数据进行转置》,本文将主要介绍根据考勤时间,计算迟到和早退的时间。
思路:迟到时间的计算时按照第一次打卡的时间和正常上班时间做比较,如果打卡时间迟于上班时间,则表示迟到,需要进行迟到时间的计算;同理,如果下班时间早于正常下班时间,则表示早退,需要进行早退时间的计算。
(注:计算迟到早退的时间与上篇的数据转置是两个独立的方法)
在进行时间计算前,需要判断DataGridViewa中是否有数据,如果没有,则进行相应的提示,并终止计算的进程。
if (rows <= 0)
{
//首先要取消 启用增加,否则默认rows为1
MessageBox.Show("该月无考勤,无法计算!");
return;
}
因DataGRivedView默认会自增一行的,如果不取消自增行,则上述的rows应该要<=1才表示DataGrivedView中无数据。
定义两个常量,正常上下班的时间,用于和用户实际的上下班时间进行比较
DateTime 正常上班时间 = Convert.ToDateTime("08:30:00");
DateTime 正常下班时间 = Convert.ToDateTime("17:30:00");
int 最少延时时间 = 1800; //延时时间超过1800秒才算延时
//计算迟到,相对简单
for (int i = 0; i<dgvAttenData.Rows.Count; i++)
{
DateTime 实际上班时间 = Convert.ToDateTime(dgvAttenData.Rows[i].Cells[6].Value.ToString());
//计算迟到
if ((正常上班时间- 实际上班时间).TotalSeconds < 0)
{
dgvAttenData.Rows[i].Cells[10].Value = (实际上班时间 - 正常上班时间);
}
//计算早退
//要考虑的问题:①如果只有一次时间记录,则不进行早退判断(todo:可以与迟到进行结合考虑、进行优化);//②如果考勤次数查过2次,要根据最后一次的的时间判断迟到次数 //③如果不早退,则计算延时时间
for (int j = 1; j < 4; j++) //如果随通过时间4到时间1来判断最后一次的刷卡时间,相对简单,但是会影响执行效率
{
if (dgvAttenData.Rows[i].Cells[6 + j].Value != null)
{
//如果该列存在值,则什么都不执行
}
else
{
//否则表示该列为空,则上列时间为最后一次刷卡时间
//获取实际的下班时间
DateTime 实际下班时间 = Convert.ToDateTime(dgvAttenData.Rows[i].Cells[6 + j-1].Value.ToString());
if ((正常下班时间 - 实际下班时间).TotalSeconds > 0)
//如果是早退,则进行数据计算
{
dgvAttenData.Rows[i].Cells[11].Value = (正常下班时间 - 实际下班时间);
break; //提高效率,直接跳出 不知是否正确?
}
if ((实际下班时间-正常下班时间).TotalSeconds > 最少延时时间)
{
dgvAttenData.Rows[i].Cells[12].Value = (实际下班时间 - 正常下班时间);
break;
}
//跳出循环
break;
}
}
}