mirror of
https://codeberg.org/scip/esctl.git
synced 2026-08-24 12:34:19 +02:00
127 lines
3.0 KiB
Go
127 lines
3.0 KiB
Go
/*
|
|
Copyright © 2026 Thomas von Dein
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
package es
|
|
|
|
import (
|
|
"fmt"
|
|
"math"
|
|
"regexp"
|
|
"strconv"
|
|
"time"
|
|
)
|
|
|
|
var (
|
|
matchDuration = regexp.MustCompile(`(\d+)([dhms])`)
|
|
)
|
|
|
|
type esDuration struct {
|
|
days, hours, minutes, seconds int
|
|
}
|
|
|
|
/*
|
|
We could use time.ParseDuration(), but this doesn't support days.
|
|
|
|
We could also use github.com/xhit/go-str2duration/v2, which does
|
|
the job, but it's just another dependency, just for this little
|
|
gem. And we don't need a time.Time value. And int is good enough
|
|
for duration comparison.
|
|
|
|
Convert a duration into an integer. Valid time units are "s", "m", "h" and "d".
|
|
|
|
via https://codeberg.org/scip/tablizer/src/branch/main/lib/sort.go#L113
|
|
*/
|
|
func parseDuration(duration string) time.Duration {
|
|
|
|
seconds := 0
|
|
|
|
for _, match := range matchDuration.FindAllStringSubmatch(duration, -1) {
|
|
if len(match) == 3 {
|
|
durationvalue, _ := strconv.Atoi(match[1])
|
|
|
|
switch match[2][0] {
|
|
case 'd':
|
|
seconds += durationvalue * 86400
|
|
case 'h':
|
|
seconds += durationvalue * 3600
|
|
case 'm':
|
|
seconds += durationvalue * 60
|
|
case 's':
|
|
seconds += durationvalue
|
|
}
|
|
}
|
|
}
|
|
|
|
return time.Duration(seconds) * time.Second
|
|
}
|
|
|
|
// pretty much the same as above, but return a struct filled with int duration values
|
|
func extractDuration(duration string) esDuration {
|
|
esd := esDuration{}
|
|
|
|
for _, match := range matchDuration.FindAllStringSubmatch(duration, -1) {
|
|
if len(match) == 3 {
|
|
durationvalue, _ := strconv.Atoi(match[1])
|
|
|
|
switch match[2][0] {
|
|
case 'd':
|
|
esd.days = durationvalue
|
|
case 'h':
|
|
esd.hours = durationvalue
|
|
case 'm':
|
|
esd.minutes = durationvalue
|
|
case 's':
|
|
esd.seconds = durationvalue
|
|
}
|
|
}
|
|
}
|
|
|
|
return esd
|
|
}
|
|
|
|
// convert a duration like 156h6m15.095s-6d/12h/6m => 6d:12h:6m
|
|
func formatDuration(val time.Duration) string {
|
|
esd := extractDuration(val.String())
|
|
|
|
daysF := float64(esd.hours) / 24.0
|
|
days := math.Floor(daysF)
|
|
hoursLeft := (daysF - days) * 24
|
|
|
|
switch {
|
|
case val.Minutes() < 1:
|
|
return fmt.Sprintf("%ds", int64(esd.seconds))
|
|
|
|
case val.Hours() < 1:
|
|
return fmt.Sprintf("%dm", int64(esd.minutes))
|
|
|
|
case val.Hours() < 24:
|
|
if esd.minutes == 0 {
|
|
return fmt.Sprintf("%dh", esd.hours)
|
|
}
|
|
return fmt.Sprintf("%dh:%dm", esd.hours, int64(esd.minutes))
|
|
|
|
default:
|
|
if esd.minutes == 0 && hoursLeft == 0 {
|
|
return fmt.Sprintf("%dd", int64(days))
|
|
}
|
|
return fmt.Sprintf("%dd:%dh:%dm",
|
|
int64(days),
|
|
int64(hoursLeft),
|
|
esd.minutes,
|
|
)
|
|
}
|
|
}
|