1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
|
package instance
import (
"errors"
"regexp"
"strconv"
"strings"
"time"
)
// ErrInvalidExpiry is returned if the provided expiry cannot be parsed.
var ErrInvalidExpiry = errors.New("Invalid expiry expression")
// GetExpiry returns the expiry date based on the reference date and a length of time.
// The length of time format is "<integer>(S|M|H|d|w|m|y)", and can contain multiple such fields, e.g.
// "1d 3H" (1 day and 3 hours).
func GetExpiry(refDate time.Time, s string) (time.Time, error) {
expr := strings.TrimSpace(s)
if expr == "" {
return time.Time{}, nil
}
re, err := regexp.Compile(`^(\d+)(S|M|H|d|w|m|y)$`)
if err != nil {
return time.Time{}, err
}
expiry := map[string]int{
"S": 0,
"M": 0,
"H": 0,
"d": 0,
"w": 0,
"m": 0,
"y": 0,
}
values := strings.Split(expr, " ")
if len(values) == 0 {
return time.Time{}, nil
}
for _, value := range values {
fields := re.FindStringSubmatch(value)
if fields == nil {
return time.Time{}, ErrInvalidExpiry
}
if expiry[fields[2]] > 0 {
// We don't allow fields to be set multiple times
return time.Time{}, ErrInvalidExpiry
}
val, err := strconv.Atoi(fields[1])
if err != nil {
return time.Time{}, err
}
expiry[fields[2]] = val
}
t := refDate.AddDate(expiry["y"], expiry["m"], expiry["d"]+expiry["w"]*7).Add(
time.Hour*time.Duration(expiry["H"]) + time.Minute*time.Duration(expiry["M"]) + time.Second*time.Duration(expiry["S"]))
return t, nil
}
|