data, err := ioutil.ReadFile(defaultPath + scheduleFileName) if err != nil { log.Printf("[Error] File %s not found: %v", defaultPath+scheduleFileName, err) } timeOffset1 := 98 timeOffset2 := 99 timeSize := 1 //first 1613 bytes reserved for table //one record use 1598 bytes //last 1600 bytes reserved for end of table for position := 1613; position < (len(data) - 1600); position += 1598 { ... timeInBytesPart1 := data[(position + timeOffset2):(position + timeOffset2 + timeSize)] timeInBytesPart2 := data[(position + timeOffset1):(position + timeOffset1 + timeSize)] totalBytes := (int(timeInBytesPart1[0]) * 256) + int(timeInBytesPart2[0]) hours := totalBytes / 100 minutes := totalBytes - hours*100 ... }
func getDate(data []uint8) time.Time { startDate := time.Date(1849, 12, 31, 0, 00, 00, 0, time.UTC) var result int for i := 0; i < len(data)-1; i++ { var sqr = 1 for j := 0; j < i; j++ { sqr = sqr * 256 } result = result + (int(data[i]) * sqr) } return startDate.AddDate(0, 0, result) }
type Schedule struct { ProviderID string `json:"provider_id"` Date time.Time `json:"date"` DayStart string `json:"day_start"` DayEnd string `json:"day_end"` Breaks *ScheduleBreaks `json:"breaks"` } type SheduleBreaks []*cheduleBreak type ScheduleBreak struct { Start time.Time `json:"start"` End time.Time `json:"end"` } func ScanSchedule(config Config) (schedules []Schedule, err error) { dataFromFile, err := ioutil.ReadFile(config.DBPath + providersFileName) if err != nil { return schedules, err } scheduleOffset := 774 weeklyDayOffset := map[string]int{ "Sunday": 0, "Monday": 12, "Tuesday": 24, "Wednesday": 36, "Thursday": 48, "Friday": 60, "Saturday": 72, } //first 1158 bytes reserved for table //one record with contact information use 1147 bytes //last 4494 bytes reserved for end of table for position := 1158; position < (len(dataFromFile) - 4494); position += 1147 { id := getIDFromSliceByte(dataFromFile[position:(position + idSize)]) //if table border (id equal "255|255"), then finish parse file if id == "255|255" { break } position := position + scheduleOffset date := time.Now() //create schedule on 3 future month (90 days) for dayNumber := 1; dayNumber < 90; dayNumber++ { schedule := Schedule{} offset := weeklyDayOffset[date.Weekday().String()] from1, to1 := getScheduleTimeFromBytes((dataFromFile[(position + offset):(position + offset + 4)]), date) from2, to2 := getScheduleTimeFromBytes((dataFromFile[(position + offset + 1):(position + offset + 4 + 1)]), date) from3, to3 := getScheduleTimeFromBytes((dataFromFile[(position + offset + 2):(position + offset + 4 + 2)]), date) //no schedule on this day if from1.IsZero() { continue } schedule.Date = time.Date(date.Year(), date.Month(), date.Day(), 0, 0, 0, 0, time.UTC) schedule.DayStart = from1.Format(time.RFC3339) switch { case to3.IsZero() == false: schedule.DayEnd = to3.Format(time.RFC3339) case to2.IsZero() == false: schedule.DayEnd = to2.Format(time.RFC3339) case to1.IsZero() == false: schedule.DayEnd = to1.Format(time.RFC3339) } if from2.IsZero() == false { scheduleBreaks := ScheduleBreaks{} scheduleBreak := ScheduleBreak{} scheduleBreak.Start = to1 scheduleBreak.End = from2 scheduleBreaks = append(scheduleBreaks, &scheduleBreak) if from3.IsZero() == false { scheduleBreak.Start = to2 scheduleBreak.End = from3 scheduleBreaks = append(scheduleBreaks, &scheduleBreak) } schedule.Breaks = &scheduleBreaks } date = date.AddDate(0, 0, 1) schedules = append(schedules, &schedule) } } return schedules, err } //getScheduleTimeFromBytes calculate bytes in time range func getScheduleTimeFromBytes(data []uint8, date time.Time) (from, to time.Time) { totalTimeFrom := int(data[0]) totalTimeTo := int(data[3]) //no schedule if totalTimeFrom == 0 && totalTimeTo == 0 { return from, to } hoursFrom := totalTimeFrom / 4 hoursTo := totalTimeTo / 4 minutesFrom := (totalTimeFrom*25 - hoursFrom*100) * 6 / 10 minutesTo := (totalTimeTo*25 - hoursTo*100) * 6 / 10 from = time.Date(date.Year(), date.Month(), date.Day(), hoursFrom, minutesFrom, 0, 0, time.UTC) to = time.Date(date.Year(), date.Month(), date.Day(), hoursTo, minutesTo, 0, 0, time.UTC) return from, to }
Source: https://habr.com/ru/post/351658/
All Articles