今天没事儿干,写个小程序,却发现逻辑性思维越来越差,梳理加班时长的关系都无法快速梳理出来,结果最终还是磕磕绊绊,马马虎虎给搞完了,果然是驱动搞的时间长了,逻辑性思维下降,脑子生锈,一切基本全凭经验,痛苦~~~
加班时长统计简单规则描述:
①正常上班时间为:周一到周五8:30上班打卡,6:00下班打卡;
②12:00-13:30为休息时间;
③如果晚上加班,则18:45以后开始计算加班时长(且如果达不到20:30以后加班无效);
④周六、周天无第③条约束(即18:00~18:45之间也为加班时间);
⑤如果早上迟到(8:30~9:00)可以使用加班来弹回;
⑥弹回规则为:8:30~8:45之间进卡,则出卡时间在7:00以后可弹回迟到统计;8:45~9:00之间进卡,则出卡时间在7:15以后可弹回迟到统计。其他无法弹回(除非提交请假公文,否则即为迟到)。
⑦调休加班时间为正常工作日;
⑧节假日加班不统计入平时加班时长(补贴不同)。
简单写了写,感觉还是脑子有点生锈,特殊情况处理不到位,处理不到位的暂时都按照异常来处理,(比如:迟到弹回机制,如果没有加班到20:30之后,但是加班时长足以弹回迟到时间,当前处理为异常),记录如下:
自个儿加班时长统计测试:
#1,3,8:17-18:04,0,1
#2,4,0:00-0:00,
#3,5,0:00-0:00,
#4,6,0:00-0:00,
#5,7,9:12-20:49,1,0,1
#6,1,8:28-21:31,
#7,2,8:36-21:25,
#8,3,8:25-21:10,
#9,4,8:23-21:37,
#10,5,8:20-20:54,
#11,6,9:50-21:49,
#12,7,10:13-19:04,
#13,1,8:26-21:50,
#14,2,8:31-21:53,
#15,3,8:23-20:52,
#16,4,8:36-21:17,
#17,5,8:39-19:45,
#18,6,8:35-20:40,
#19,7,13:21-19:27
#20,1,8:49-18:40,
#21,2,
#22,3,
#23,4,
#24,5,
#25,6,
#26,7,
#27,1,
#28,2,
#29,3,
#30,4,
#31,5,
前16天(去掉5.1~5.5,基本就是10天)已经加了40多个小时,还是有点难受,周末还在这撸代码,算加班时长能不能达到要求,这是真的被人贩子卖了还要帮人贩子数钱の感觉。
Krj@VM:/mnt/hgfs/O/NotesAndCodes/11_OtherCodeTest/CalcOvertime$ ./OvertimeTable.exe OvertimeTable.txt
Krj@VM:/mnt/hgfs/O/NotesAndCodes/11_OtherCodeTest/CalcOvertime$ cat OvertimeTable.txt.result
Total overtime minutes:3565 [hours:59.416667], exclude hoilday day
Details of each day are shown below:
DayIndex Week StartStamp EndStamp SleepTime Hours Minutes Rebound Holiday adjust leaveFlag Exception
1 Wednesday 497 1084 90 8.066667 484 0 1 0 0 Normal
2 Thursday 0 0 0 0.000000 0 0 0 0 0 Normal
3 Friday 0 0 0 0.000000 0 0 0 0 0 Normal
4 Saturday 0 0 0 0.000000 0 0 0 0 0 Normal
5 Sunday 510 1249 135 2.066667 124 0 0 1 1 Normal
6 Monday 508 1291 135 2.766667 166 0 0 0 0 Normal
7 Tuesday 516 1285 135 2.416667 145 15 0 0 0 Normal
8 Wednesday 505 1270 135 2.416667 145 0 0 0 0 Normal
9 Thursday 503 1297 135 2.866667 172 0 0 0 0 Normal
10 Friday 500 1254 135 2.150000 129 0 0 0 0 Normal
11 Saturday 590 1309 90 10.483333 629 0 0 0 0 Normal
12 Sunday 613 1144 90 7.350000 441 0 0 0 0 Normal
13 Monday 506 1310 135 3.083333 185 0 0 0 0 Normal
14 Tuesday 511 1313 135 2.883333 173 15 0 0 0 Normal
15 Wednesday 503 1252 135 2.116667 127 0 0 0 0 Normal
16 Thursday 516 1277 135 2.283333 137 15 0 0 0 Normal
17 Friday 519 1185 0 0.000000 0 0 0 0 0 Normal
18 Saturday 515 1240 90 10.583333 635 0 0 0 0 Normal
19 Sunday 801 1167 9 5.950000 357 0 0 0 0 Normal
20 Monday 529 1120 0 0.000000 0 0 0 0 0 Exception
21 Tuesday 0 0 0 0.000000 0 0 0 0 0 Normal
22 Wednesday 0 0 0 0.000000 0 0 0 0 0 Normal
23 Thursday 0 0 0 0.000000 0 0 0 0 0 Normal
24 Friday 0 0 0 0.000000 0 0 0 0 0 Normal
25 Saturday 0 0 0 0.000000 0 0 0 0 0 Normal
26 Sunday 0 0 0 0.000000 0 0 0 0 0 Normal
27 Monday 0 0 0 0.000000 0 0 0 0 0 Normal
28 Tuesday 0 0 0 0.000000 0 0 0 0 0 Normal
29 Wednesday 0 0 0 0.000000 0 0 0 0 0 Normal
30 Thursday 0 0 0 0.000000 0 0 0 0 0 Normal
31 Friday 0 0 0 0.000000 0 0 0 0 0 Normal
Krj@VM:/mnt/hgfs/O/NotesAndCodes/11_OtherCodeTest/CalcOvertime$
该计算方法核心两点:
①多种情况的分类合并(或异常情况的特殊化处理/不处理);
②数据结构的组织与处理方式的配合使用。
1、分类:
根据描述可知:每天的加班时长和入卡时间、出卡时间、休息时长、迟到弹回以及正常上班时长有关系。而可以分为周内(1,2,3,4,5)&周末(6,7)两种,因为这两类区别最大(①晚上加班sleep时间有区别;②周末不需要计算弹回;③周末无上班时长,只有加班时长;④周内的异常计算情况比较多等)。
周内以入卡时间和出卡时间来限定sleep、rebound的时长;周末默认工作时长和弹回的rebound时长均为0,统一的计算方式如下:
overTime = endTime - startTime - reboundTime - sleepTime - workTime;
/* 加班时长 = 出卡时间 - 入卡时间 - 迟到需弹回时长 - 休息时长 - 工作时长 */
特殊情况:①而周内/周末可能还有是节假日加班的情况(hoildayFlag标志来标记),也统一同周末一样计算加班时长,但是不汇总到月加班统计和之中去;②周内/周末也有可能是节假日放假调休的加班(adjustFlag标志来标记),这种也算是正常上班,因此也按照正常周内上班的加班来计算加班时长。以上两种特殊情况,都是由于按照周内/周末的分类方法来分属于周末(①属于但是不等于周末)和周内(②等价于周内)的。
2、数据结构:
每一天的统计信息如下(有基本打卡信息和计算信息以及标志信息等):
typedef struct day_time_info{
UINT32 dayIndex; /* 该天是该月第几天(从1开始) */
UINT32 sleepTime; /* 非加班/上班时间(茶歇午休等) */
UINT32 startTimeStamp; /* 上班时间时间戳(基于00:00:00) */
UINT32 endTimeStamp; /* 下班时间时间戳(基于00:00:00) */
UINT32 minutes; /* 该天加班分钟数 */
DOUBLE hours; /* 该天小时数 */
UINT32 reboundTime; /* 弹回时长 */
BOOL leaveFlag; /* 迟到不可弹回时的请假(调休)标志 */
BOOL holidayFlag; /* 该天是假日标志 */
BOOL adjustFlag; /* 该天是非周内,但是属于节假日调休加班即正常上班 */
BOOL exceptionFlag; /* 异常标志 */
WEEK week; /* 该天是周几 */
}DAYINFO;
一个月的overTime数据结构如下所示:
#define ONE_MONTH_MAX_DAYS 31
typedef struct over_time_ifo{
UINT32 overtimeDay; /* 加班天数(按照实际天计算) */
UINT32 totalMinutes; /* 总加班时长(分钟) */
DOUBLE totalHours; /* 总加班时长(小时) */
DAYINFO day[ONE_MONTH_MAX_DAYS];
}OVERTIEINFO;