package strutilimport ()var regNumVersion = regexp.MustCompile(`[0-9][\d.]+([_-]\d+)?`)// NumVersion parse input string, get valid number version. eg: go-1.22.3 -> 1.22.3func ( string) string {returnregNumVersion.FindString()}// MustToTime convert date string to time.Timefunc ( string, ...string) time.Time { , := ToTime(, ...)if != nil {panic() }return}// auto match uses some common layouts.// key is layout length.var layoutMap = map[int][]string{6: {"200601", "060102", time.Kitchen},8: {"20060102", "06-01-02"},10: {"2006-01-02"},13: {"2006-01-02 15"},15: {time.Stamp},16: {"2006-01-02 15:04"},19: {"2006-01-02 15:04:05", time.RFC822, time.StampMilli},20: {"2006-01-02 15:04:05Z"},21: {time.RFC822Z},22: {time.StampMicro},23: {"2006-01-02 15:04:05.000", "2006-01-02 15:04:05.999"},24: {time.ANSIC},25: {time.RFC3339, time.StampNano},// time.Layout}, // must go >= 1.1926: {"2006-01-02 15:04:05.000000"},28: {time.UnixDate},29: {time.RFC1123, "2006-01-02 15:04:05.000000000"},30: {time.RFC850},31: {time.RFC1123Z},35: {time.RFC3339Nano},}// ToTime convert date string to time.Time//// NOTE: always use local timezone.func ( string, ...string) ( time.Time, error) {returnToTimeIn(, time.Local, ...)}// ToTimeIn convert date string to time.Time with location.func ( string, *time.Location, ...string) ( time.Time, error) {if == nil { = time.Local }// custom layoutiflen() > 0 {iflen([0]) > 0 {returntime.ParseInLocation([0], , ) } = ErrDateLayoutreturn }// auto match use some commonly layouts. := len() , := layoutMap[]if ! { = ErrInvalidParamreturn }varboolif := strings.IndexByte(, 'T'); > 0 && < 12 { = true } := strings.IndexByte(, '/') > 0for , := range {// date string has "T". eg: "2006-01-02T15:04:05"if { = strings.Replace(, " ", "T", 1) }// date string has "/". eg: "2006/01/02 15:04:05"if { = strings.ReplaceAll(, "-", "/") }if > 10 && [10] != ' ' && len() > 10 && [10] == ' ' { = [:10] + string([10]) + [11:] } , = time.ParseInLocation(, , )if == nil {return } }// t, err = time.ParseInLocation(layout, s, loc)return}// ParseSizeOpt parse size expression optionstypeParseSizeOptstruct {// OneAsMax if only one size value, use it as max size. default is false OneAsMax bool// SepChar is the separator char for time range string. default is '~' SepChar byte// KeywordFn is the function for parse keyword time string. KeywordFn func(string) (min, max uint64, err error)}func ensureOpt( *ParseSizeOpt) *ParseSizeOpt {if == nil { = &ParseSizeOpt{SepChar: '~'} } else {if .SepChar == 0 { .SepChar = '~' } }return}// ErrInvalidSizeExpr invalid size expression errorvarErrInvalidSizeExpr = errors.New("invalid size expr")// ParseSizeRange parse range size expression to min and max size.//// Expression format://// "1KB~2MB" => 1KB to 2MB// "-1KB" => <1KB// "~1MB" => <1MB// "< 1KB" => <1KB// "1KB" => >1KB// "1KB~" => >1KB// ">1KB" => >1KB// "+1KB" => >1KBfunc ( string, *ParseSizeOpt) (, uint64, error) { = ensureOpt() = strings.TrimSpace()if == "" { = ErrInvalidSizeExprreturn }// parse size range. eg: "1KB~2MB"ifstrings.IndexByte(, '~') > -1 { , := TrimCut(, "~")if != "" { , = ToByteSize()if != nil {return } }if != "" { , = ToByteSize() }return }// parse single size. eg: "1KB"ifbyteutil.IsNumChar([0]) { , = ToByteSize()if != nil {return }if .OneAsMax { = }return }// parse with prefix. eg: "<1KB", ">= 1KB", "-1KB", "+1KB"switch [0] {case'<', '-': , = ToByteSize(strings.Trim([1:], " ="))case'>', '+': , = ToByteSize(strings.Trim([1:], " ="))default:// parse keyword. eg: "small", "large"if .KeywordFn != nil { , , = .KeywordFn() } else { = ErrInvalidSizeExpr } }return}// SafeByteSize converts size string like 1GB/1g or 12mb/12M into an unsigned integer number of bytesfunc ( string) uint64 { , := ToByteSize()return}// ToByteSize converts size string like 1GB/1g or 12mb/12M into an unsigned integer number of bytesfunc ( string) (uint64, error) { = strings.TrimSpace() := len() - 1if < 0 {return0, nil }if [] == 'b' || [] == 'B' {// last second char is k,m,g,t := [-1]if > 'A' { -- } } elseifIsNumChar([]) { // not unit suffix. eg: 346returnstrconv.ParseUint(, 10, 32) } := float64(1)switchunicode.ToLower(rune([])) {case'k': = 1 << 10case'm': = 1 << 20case'g': = 1 << 30case't': = 1 << 40case'p': = 1 << 50default: // b = 1 } := strings.TrimSpace([:]) , := strconv.ParseFloat(, 64)if != nil {return0, }returnuint64( * ), nil}
The pages are generated with Goldsv0.8.4. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.