1
1
mirror of https://github.com/go-gitea/gitea synced 2024-12-23 00:54:28 +00:00
gitea/modules/util/time_str.go
silverwind 626b27bea5
Update go tool dependencies (#32916)
Update all go tool dependencies to latest version. WIP because I think
there are new gopls errors, would like to confirm them on CI first. Here
is from a local run:

```
modules/markup/markdown/goldmark.go:115:37-53: unnecessary type arguments
modules/markup/html.go:45:32-49: unnecessary type arguments
modules/markup/internal/renderinternal.go:20:33-49: unnecessary type arguments
modules/markup/common/linkify.go:27:32-49: unnecessary type arguments
modules/util/time_str.go:28:39-63: unnecessary type arguments
routers/web/repo/pull.go:704:19: impossible condition: non-nil == nil
modules/util/util_test.go:248:14-23: unused parameter: other
```

~~Backport because the `gxz` update might have security benefits.~~
2024-12-19 19:17:55 +01:00

86 lines
2.0 KiB
Go

// Copyright 2024 Gitea. All rights reserved.
// SPDX-License-Identifier: MIT
package util
import (
"fmt"
"regexp"
"strconv"
"strings"
"sync"
)
type timeStrGlobalVarsType struct {
units []struct {
name string
num int64
}
re *regexp.Regexp
}
// When tracking working time, only hour/minute/second units are accurate and could be used.
// For other units like "day", it depends on "how many working hours in a day": 6 or 7 or 8?
// So at the moment, we only support hour/minute/second units.
// In the future, it could be some configurable options to help users
// to convert the working time to different units.
var timeStrGlobalVars = sync.OnceValue(func() *timeStrGlobalVarsType {
v := &timeStrGlobalVarsType{}
v.re = regexp.MustCompile(`(?i)(\d+)\s*([hms])`)
v.units = []struct {
name string
num int64
}{
{"h", 60 * 60},
{"m", 60},
{"s", 1},
}
return v
})
func TimeEstimateParse(timeStr string) (int64, error) {
if timeStr == "" {
return 0, nil
}
var total int64
matches := timeStrGlobalVars().re.FindAllStringSubmatchIndex(timeStr, -1)
if len(matches) == 0 {
return 0, fmt.Errorf("invalid time string: %s", timeStr)
}
if matches[0][0] != 0 || matches[len(matches)-1][1] != len(timeStr) {
return 0, fmt.Errorf("invalid time string: %s", timeStr)
}
for _, match := range matches {
amount, err := strconv.ParseInt(timeStr[match[2]:match[3]], 10, 64)
if err != nil {
return 0, fmt.Errorf("invalid time string: %v", err)
}
unit := timeStr[match[4]:match[5]]
found := false
for _, u := range timeStrGlobalVars().units {
if strings.ToLower(unit) == u.name {
total += amount * u.num
found = true
break
}
}
if !found {
return 0, fmt.Errorf("invalid time unit: %s", unit)
}
}
return total, nil
}
func TimeEstimateString(amount int64) string {
var timeParts []string
for _, u := range timeStrGlobalVars().units {
if amount >= u.num {
num := amount / u.num
amount %= u.num
timeParts = append(timeParts, fmt.Sprintf("%d%s", num, u.name))
}
}
return strings.Join(timeParts, " ")
}