今天沒事兒幹,寫個小程序,卻發現邏輯性思維越來越差,梳理加班時長的關係都無法快速梳理出來,結果最終還是磕磕絆絆,馬馬虎虎給搞完了,果然是驅動搞的時間長了,邏輯性思維下降,腦子生鏽,一切基本全憑經驗,痛苦~~~
加班時長統計簡單規則描述:
①正常上班時間爲:週一到週五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;