mirror of
https://codeberg.org/scip/ts.git
synced 2026-08-24 14:54:20 +02:00
143 lines
2.9 KiB
Go
143 lines
2.9 KiB
Go
package runexpr
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"math"
|
|
"strconv"
|
|
"time"
|
|
)
|
|
|
|
const maxDuration time.Duration = 1<<63 - 1
|
|
|
|
// humanDuration represents a ES duration with day support
|
|
type humanDuration struct {
|
|
days, hours, minutes, seconds int
|
|
}
|
|
|
|
func parseDuration(duration string) time.Duration {
|
|
var seconds int64
|
|
|
|
for _, match := range matchDuration.FindAllStringSubmatch(duration, -1) {
|
|
if len(match) == 3 {
|
|
durationvalue, err := strconv.ParseInt(match[1], 10, 64)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
switch match[2][0] {
|
|
case 'y':
|
|
seconds += durationvalue * 31536000
|
|
case 'd':
|
|
seconds += durationvalue * 86400
|
|
case 'h':
|
|
seconds += durationvalue * 3600
|
|
case 'm':
|
|
seconds += durationvalue * 60
|
|
case 's':
|
|
seconds += durationvalue
|
|
}
|
|
}
|
|
}
|
|
|
|
if seconds >= int64(maxDuration.Seconds()) {
|
|
log.Fatal("duration overflow, choose a smaller duration")
|
|
}
|
|
|
|
dur := time.Duration(seconds) * time.Second
|
|
|
|
return dur
|
|
}
|
|
|
|
// extractDuration parses a ES duration and returns an esDuration
|
|
func extractDuration(duration string) humanDuration {
|
|
esd := humanDuration{}
|
|
|
|
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
|
|
}
|
|
|
|
// formatDays returns days string, unless days is larger than 365,
|
|
// then it returns years and days, e.g. 3y/34d
|
|
func formatDays(days float64) string {
|
|
if days > 365 {
|
|
years := days / 365
|
|
days := math.Remainder(days, 365)
|
|
return fmt.Sprintf("%dy/%dd", int64(years), int64(days))
|
|
}
|
|
|
|
return fmt.Sprintf("%dd", int64(days))
|
|
}
|
|
|
|
// formatDuration converts a time.Duration to a prettier human
|
|
// readable form, 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 formatDays(days)
|
|
}
|
|
|
|
return fmt.Sprintf("%s/%dh/%dm",
|
|
formatDays(days),
|
|
int64(hoursLeft),
|
|
esd.minutes,
|
|
)
|
|
}
|
|
}
|
|
|
|
func toYears(d time.Duration) float64 {
|
|
return d.Hours() / 24 / 365
|
|
}
|
|
|
|
func toDays(d time.Duration) float64 {
|
|
return d.Hours() / 24
|
|
}
|
|
|
|
func toHours(d time.Duration) float64 {
|
|
return d.Hours()
|
|
}
|
|
|
|
func toMinutes(d time.Duration) float64 {
|
|
return d.Minutes()
|
|
}
|
|
|
|
func toSeconds(d time.Duration) float64 {
|
|
return d.Seconds()
|
|
}
|