package comfuncimport ()var (// check is duration string. TIP: extend unit d,w. eg: "1d", "2w" // // time.ParseDuration() is max support hour "h". durStrReg = regexp.MustCompile(`^-?([0-9]+(?:\.[0-9]*)?(ns|us|µs|ms|s|m|h|d|w))+$`)// check long duration string. 验证整体格式是否符合 // // eg: "1hour", "2hours", "3minutes", "4mins", "5days", "1weeks", "1month" // // time.ParseDuration() is not support long unit. durStrRegL = regexp.MustCompile(`^-?([0-9]+(?:\.[0-9]*)?[nuµsmhdw][a-zA-Z]{0,8})+$`)// use for parse duration string. see ToDuration() // // NOTE: 解析时,不能加最后的 `+` 会导致只匹配了最后一组 时间单位 durStrRegL2 = regexp.MustCompile(`-?([0-9]+(?:\.[0-9]*)?)([nuµsmhdw][a-z]{0,8})`))// IsDuration check the string is a duration string.func ( string) bool {if == "0" || durStrReg.MatchString() {returntrue }returndurStrRegL.MatchString()}// ToDuration parses a duration string. such as "300ms", "-1.5h" or "2h45m".// Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".//// Diff of time.ParseDuration:// - support extends unit d, w at the end of string. such as "1d", "2w".// - support extends unit: month, week, day// - support long string unit at the end. such as "1hour", "2hours", "3minutes", "4mins", "5days", "1weeks".//// If the string is not a valid duration string, it will return an error.func ( string) (time.Duration, error) { := len()if == 0 {return0, fmt.Errorf("empty duration string") } = strings.ToLower()if == "0" {return0, nil }// check duration string is validif !durStrRegL.MatchString() {return0, fmt.Errorf("invalid duration string: %s", ) }// if ln < 4 AND end != d|w, directly call time.ParseDuration()if < 4 && [-1] != 'd' && [-1] != 'w' {returntime.ParseDuration() }// time.ParseDuration() is not support long unit. := durStrRegL2.FindAllStringSubmatch(, -1)// fmt.Println(ssList) := make([]byte, 0, )if [0] == '-' { = append(, '-') }// only one element. eg: "1day"iflen() == 1 { = parseLongUnit([0], ) } else {// more than one element. eg: "1day2hour3min"for , := range {iflen() == 3 { = parseLongUnit(, ) } } }returntime.ParseDuration(string())}// convert to short unitfunc parseLongUnit( []string, []byte) []byte {// eg: "3sec" -> ss=[3sec, -3, sec] , := [1], [2]switch {case"month", "months":// time lib max unit is hour, so need convert by 24 * 30*n = appendNumToBytes(, , 24*30) = append(, 'h')case"w", "week", "weeks":// time lib max unit is hour, so need convert by 24 * 7*n = appendNumToBytes(, , 24*7) = append(, 'h')case"d", "day", "days":// time lib max unit is hour, so need convert by 24*n = appendNumToBytes(, , 24) = append(, 'h')case"hour", "hours": = append(, ...) = append(, 'h')case"min", "mins", "minute", "minutes": = append(, ...) = append(, 'm')case"sec", "secs", "second", "seconds": = append(, ...) = append(, 's')default: := [0]// '-' has been added on ToDuration()if [0] == '-' { = append(, [1:]...) } else { = append(, ...) } }return}func appendNumToBytes( []byte, string, int) []byte {ifstrings.ContainsRune(, '.') { , := strconv.ParseFloat(, 64) // is float number := * float64()// 使用 Float 保留两位小数 -> 会始终有两位小数,即使是N.00 // bts = strconv.AppendFloat(bts, val, 'f', 2, 64)// 四舍五入到两位小数 := math.Round(*100) / 100// 使用 AppendFloat 自动去除末尾的 .0 或 .00 = strconv.AppendFloat(, , 'f', -1, 64) } else { , := strconv.Atoi() = strconv.AppendInt(, int64(*), 10) }return}
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.