這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
package mainimport "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") }}