package main import ( "fmt" "strconv" "strings" "time" ) type TimeRange struct { after int before int } type WeeklyRanges struct { ranges [7][]TimeRange } type TimeRangeStr struct { After string Before string } type WeeklyRangesStr struct { Sun, Mon, Tue, Wed, Thu, Fri, Sat []TimeRangeStr } func daySecsFromStr(str string) (int, error) { parts := strings.Split(str, ":") if len(parts) != 2 { return -1, fmt.Errorf("Syntax error in a time expression: [%s]", str) } hours, err := strconv.Atoi(parts[0]) if err != nil || hours < 0 || hours > 23 { return -1, fmt.Errorf("Syntax error in a time expression: [%s]", str) } minutes, err := strconv.Atoi(parts[1]) if err != nil || minutes < 0 || minutes > 59 { return -1, fmt.Errorf("Syntax error in a time expression: [%s]", str) } return (hours*60 + minutes) * 60, nil } func parseTimeRanges(timeRangesStr []TimeRangeStr) ([]TimeRange, error) { timeRanges := []TimeRange{} for _, timeRangeStr := range timeRangesStr { after, err := daySecsFromStr(timeRangeStr.After) if err != nil { return timeRanges, err } before, err := daySecsFromStr(timeRangeStr.Before) if err != nil { return timeRanges, err } if after == before { after, before = -1, 86402 } timeRanges = append(timeRanges, TimeRange{after: after, before: before}) } return timeRanges, nil } func parseWeeklyRanges(weeklyRangesStr WeeklyRangesStr) (WeeklyRanges, error) { weeklyRanges := WeeklyRanges{} weeklyRangesStrX := [7][]TimeRangeStr{ weeklyRangesStr.Sun, weeklyRangesStr.Mon, weeklyRangesStr.Tue, weeklyRangesStr.Wed, weeklyRangesStr.Thu, weeklyRangesStr.Fri, weeklyRangesStr.Sat, } for day, weeklyRangeStrX := range weeklyRangesStrX { timeRanges, err := parseTimeRanges(weeklyRangeStrX) if err != nil { return weeklyRanges, err } weeklyRanges.ranges[day] = timeRanges } return weeklyRanges, nil } func ParseAllWeeklyRanges(allWeeklyRangesStr map[string]WeeklyRangesStr) (*map[string]WeeklyRanges, error) { allWeeklyRanges := make(map[string]WeeklyRanges) for weeklyRangesName, weeklyRangesStr := range allWeeklyRangesStr { weeklyRanges, err := parseWeeklyRanges(weeklyRangesStr) if err != nil { return nil, err } allWeeklyRanges[weeklyRangesName] = weeklyRanges } return &allWeeklyRanges, nil } func (weeklyRanges *WeeklyRanges) Match() bool { now := time.Now().Local() day := now.Weekday() weeklyRange := weeklyRanges.ranges[day] if len(weeklyRange) == 0 { return false } hour, min, _ := now.Clock() nowX := (hour*60 + min) * 60 for _, timeRange := range weeklyRange { if timeRange.after > timeRange.before { if nowX >= timeRange.after || nowX <= timeRange.before { return true } } else if nowX >= timeRange.after && nowX <= timeRange.before { return true } } return false }