forked from ITAnt/SecondProject
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathworkhour
More file actions
157 lines (131 loc) · 4.36 KB
/
workhour
File metadata and controls
157 lines (131 loc) · 4.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
package main
import "flag"
import "fmt"
import "bufio"
import "os"
import "strconv"
import "strings"
var infile *string = flag.String("i", "before.txt", "Work hours to convert")
var outfile *string = flag.String("o", "after.txt", "Work hours converted")
// 声明一个变量,用来临时记录新一行的数据
var newLine string
// 声明一个slice,用他来保存所有新行数据
var newLines []string
/**
* 请手动去掉有请假或迟到、早退的行(这些情况需要特殊处理)
* 计算正常上下班,当天没有请假、早退情况的上班时间(单位:小时),保留到小数点后面两位数字。
* 计算之前的文件请命名为before.txt,放在该代码同级目录下。
* go语言排序
*/
func main() {
// 初始化保存新行数据的slice,由于每个月最多31天,所以给它分配初始大小为32,多一行打印平均时间
newLines = make([]string, 32)
flag.Parse()
if infile != nil {
fmt.Println("infile=", *infile, "outfile=", *outfile)
}
// 打开未处理的文件
file, err := os.Open(*infile)
if err != nil {
fmt.Println("打开文件失败", infile)
return
}
defer file.Close()
br := bufio.NewReader(file)
sumHour := 0.0
index := 0
for {
// 每次读取一行,都让新行归位为空
newLine = ""
// 读取一行数据
line, isPrefix, readLineErr := br.ReadLine()
if readLineErr != nil {
// 已经读完了
break
}
if isPrefix {
// 行太长了,无法处理,退出程序
fmt.Println("行太长了")
return
}
// 字符数组转为字符串
str := string(line)
// 按制表符分割一行数据,第0个字符串为日期,第1个数据为上班时间,第2个数据为下班
strs := strings.Split(str, "\t")
// 让新行先记录下日期
newLine = strs[0] + " "
// 处理上班时间,根据冒号进行分割,前者为小时,后者为分钟
start := strings.Split(strs[1], ":")
startHour, startHourErr := strconv.Atoi(start[0])
if startHourErr != nil {
// 转换上班小时的时候出错了
fmt.Println("转换上班的小时出现错误")
return
}
startMinute, startMinuteErr := strconv.Atoi(start[1])
if startMinuteErr != nil {
// 转换上班分钟的时候出错了
fmt.Println("转换上班的分钟出现错误")
return
}
// 处理下班时间,根据冒号进行分割,前者为小时,后者为分钟
end := strings.Split(strs[2], ":")
endHour, endHourErr := strconv.Atoi(end[0])
if endHourErr != nil {
// 转换下班小时的时候出错了
fmt.Println("转换下班的小时出现错误")
return
}
endMinute, endMinuteErr := strconv.Atoi(end[1])
if endMinuteErr != nil {
// 转换下班分钟的时候出错了
fmt.Println("转换下班的分钟出现错误")
return
}
// 过滤不符合要求的时间(有迟到)
if startHour > 9 {
// 迟到
fmt.Println("请去除迟到的时间")
return
}
// 过滤不符合要求的时间(有早退)
if endHour == 17 && endMinute < 30 || endHour < 17 {
// 早退
fmt.Println("请去除早退的时间")
return
}
// 小数形式的每天上班时间
currentDayHour := 0.0
// 上班时间转换为小数形式
startFloat := float64(float64(startHour) + float64(startMinute)/60)
// 小数形式的下班时间
endFloat := 0.0
// 由于5:30到6:00是吃饭时间,不计入工时,所以要分情况处理
if endHour < 18 {
// 处于下午5点半到6点之间,相当于17:30下班,也就是下班点为17.5
endFloat = 17.5
} else {
// 6点之后下班,直接减去30/60小时
endFloat = float64(float64(endHour) + float64(endMinute)/60 - 0.5)
}
// 减去1.5小时的中午休息时间就是当天上班时间
currentDayHour = endFloat - startFloat - 1.5
sumHour += currentDayHour
// 保存新一行数据到slice中currentDayHour
newLines[index] = newLine + strconv.FormatFloat(currentDayHour, 'f', 2, 64)
index++
}
average := sumHour / float64(index)
newLines[index] = "平均每天上班时间:" + strconv.FormatFloat(average, 'f', 2, 64) + "小时"
// 保存文件
afterFile, afterErr := os.Create(*outfile)
if afterErr != nil {
fmt.Println("创建输出文件失败")
return
}
defer afterFile.Close()
// 将slice倒转过来输出,让时间从小到大
for i := len(newLines) - 1; i >= 0; i-- {
afterFile.WriteString(newLines[i] + "\r\n")
}
}