package cronFormat import ( "strings" cherryError "github.com/cherry-game/cherry/error" cherryString "github.com/cherry-game/cherry/extend/string" "github.com/spf13/cast" ) const ( questionMarkChar = "?" asteriskChar = "*" hyphenChar = "-" commaChar = "," slashChar = "/" colonChar = ":" ) func getSpecHour(spec string) (int32, int32, error) { strSplit := strings.Split(spec, hyphenChar) if len(strSplit) != 2 { return 0, 0, cherryError.Errorf("parse error! [value = %s]", spec) } var ( starOK bool endOK bool startSeconds int32 endSeconds int32 ) startSeconds, starOK = toSeconds(strSplit[0]) endSeconds, endOK = toSeconds(strSplit[1]) if !starOK || !endOK { return 0, 0, cherryError.Errorf("parse error! [value = %s]", spec) } return startSeconds, endSeconds, nil } func toSeconds(specHour string) (int32, bool) { strSplit := strings.Split(specHour, colonChar) if len(strSplit) != 2 { return 0, false } hour, ok := cherryString.ToInt(strSplit[0]) if !ok { return 0, false } if !hours.inRange(hour) { return 0, false } minute, ok := cherryString.ToInt(strSplit[1]) if !ok { return 0, false } if !minutes.inRange(minute) { return 0, false } return int32((hour*60 + minute) * 60), true } func getSpec(spec string, b bounds) ([]int, error) { val, ok := isValue(spec, b) if ok { return val, nil } val, ok = isQuestionMark(spec, b) if ok { return val, nil } val, ok = isAsterisk(spec, b) if ok { return val, nil } val, ok = isHyphen(spec, b) if ok { return val, nil } val, ok = isComma(spec, b) if ok { return val, nil } val, ok = isSlash(spec, b) if ok { return val, nil } err := cherryError.Errorf("parse error! [value = %s]", spec) return nil, err } // isValue 解析 正常值格式 func isValue(str string, b bounds) ([]int, bool) { intValue, ok := cherryString.ToInt(str) if !ok { return nil, false } if !b.inRange(intValue) { return nil, false } return []int{intValue}, true } // isQuestionMark 解析 ? 格式 func isQuestionMark(str string, _ bounds) ([]int, bool) { if str == questionMarkChar { return []int{}, true } return nil, false } // isAsterisk 解析 * 格式 func isAsterisk(str string, b bounds) ([]int, bool) { if str == asteriskChar { return b.all, true } return nil, false } // isHyphen 解析 - 格式 func isHyphen(str string, b bounds) ([]int, bool) { if !strings.Contains(str, hyphenChar) { return nil, false } strSplit := strings.Split(str, hyphenChar) if len(strSplit) != 2 { return nil, false } start, e1 := cast.ToIntE(strSplit[0]) end, e2 := cast.ToIntE(strSplit[1]) if e1 != nil || e2 != nil { return nil, false } if start > end { return nil, false } if !b.inRange(start) { return nil, false } if !b.inRange(end) { return nil, false } var values []int for i := start; i <= end; i++ { values = append(values, i) } return values, true } // isComma 解析 , 格式 func isComma(str string, b bounds) ([]int, bool) { if !strings.Contains(str, commaChar) { return nil, false } strSplit := strings.Split(str, commaChar) if len(strSplit) < 1 { return nil, false } var values []int for _, s := range strSplit { v, err := cast.ToIntE(s) if err != nil { return nil, false } if !b.inRange(v) { return nil, false } values = append(values, v) } return values, true } // isSlash 解析 / 格式 func isSlash(str string, b bounds) ([]int, bool) { if !strings.Contains(str, slashChar) { return nil, false } strSplit := strings.Split(str, slashChar) if len(strSplit) != 2 { return nil, false } var values []int for _, s := range strSplit { v, err := cast.ToIntE(s) if err != nil { return nil, false } if !b.inRange(v) { return nil, false } values = append(values, v) } return values, true }