authelia/internal/utils/time.go
James Elliott 6276883f04
refactor(configuration): utilize time duration decode hook (#2938)
This enhances the existing time.Duration parser to allow multiple units, and implements a decode hook which can be used by koanf to decode string/integers into time.Durations as applicable.
2022-03-02 17:40:26 +11:00

70 lines
1.8 KiB
Go

package utils
import (
"fmt"
"strconv"
"time"
)
// StandardizeDurationString converts units of time that stdlib is unaware of to hours.
func StandardizeDurationString(input string) (output string, err error) {
if input == "" {
return "0s", nil
}
matches := reDurationStandard.FindAllStringSubmatch(input, -1)
if len(matches) == 0 {
return "", fmt.Errorf("could not parse '%s' as a duration", input)
}
var d int
for _, match := range matches {
if d, err = strconv.Atoi(match[1]); err != nil {
return "", fmt.Errorf("could not parse the numeric portion of '%s' in duration string '%s': %w", match[0], input, err)
}
unit := match[2]
switch {
case IsStringInSlice(unit, standardDurationUnits):
output += fmt.Sprintf("%d%s", d, unit)
case unit == DurationUnitDays:
output += fmt.Sprintf("%dh", d*HoursInDay)
case unit == DurationUnitWeeks:
output += fmt.Sprintf("%dh", d*HoursInWeek)
case unit == DurationUnitMonths:
output += fmt.Sprintf("%dh", d*HoursInMonth)
case unit == DurationUnitYears:
output += fmt.Sprintf("%dh", d*HoursInYear)
default:
return "", fmt.Errorf("could not parse the units portion of '%s' in duration string '%s': the unit '%s' is not valid", match[0], input, unit)
}
}
return output, nil
}
// ParseDurationString standardizes a duration string with StandardizeDurationString then uses time.ParseDuration to
// convert it into a time.Duration.
func ParseDurationString(input string) (duration time.Duration, err error) {
if reDurationSeconds.MatchString(input) {
var seconds int
if seconds, err = strconv.Atoi(input); err != nil {
return 0, nil
}
return time.Second * time.Duration(seconds), nil
}
var out string
if out, err = StandardizeDurationString(input); err != nil {
return 0, err
}
return time.ParseDuration(out)
}