mirror of
https://github.com/absmach/supermq.git
synced 2026-06-23 06:20:18 +00:00
67180a55f7
* update MG errors Signed-off-by: Arvindh <arvindh91@gmail.com> * update MG errors Signed-off-by: Arvindh <arvindh91@gmail.com> * sync with supermq main Signed-off-by: Arvindh <arvindh91@gmail.com> * update MG errors Signed-off-by: Arvindh <arvindh91@gmail.com> --------- Signed-off-by: Arvindh <arvindh91@gmail.com>
87 lines
1.8 KiB
Go
87 lines
1.8 KiB
Go
// Copyright (c) Abstract Machines
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package reltime
|
|
|
|
import (
|
|
"fmt"
|
|
"regexp"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/absmach/supermq/pkg/errors"
|
|
)
|
|
|
|
var (
|
|
re = regexp.MustCompile(`(?i)^now\(\)([\+\-])(.+)$`)
|
|
|
|
ErrInvalidDuration = errors.New("invalid duration format")
|
|
ErrInvalidExpression = errors.New("invalid time expression")
|
|
ErrUnsupportedUnit = errors.New("unsupported unit")
|
|
)
|
|
|
|
func Parse(expr string) (time.Time, error) {
|
|
now := time.Now().UTC()
|
|
expr = strings.ReplaceAll(expr, " ", "")
|
|
|
|
if strings.EqualFold(expr, "now()") {
|
|
return now, nil
|
|
}
|
|
|
|
matches := re.FindStringSubmatch(expr)
|
|
if len(matches) != 3 {
|
|
return time.Time{}, errors.Wrap(ErrInvalidExpression, fmt.Errorf("%s", expr))
|
|
}
|
|
|
|
sign := matches[1]
|
|
durStr := matches[2]
|
|
if strings.ContainsAny(durStr, "+-") {
|
|
return time.Time{}, errors.Wrap(ErrInvalidExpression, fmt.Errorf("%s", expr))
|
|
}
|
|
|
|
dur, err := parseComplexDuration(durStr)
|
|
if err != nil {
|
|
return time.Time{}, err
|
|
}
|
|
|
|
if sign == "-" {
|
|
return now.Add(-dur), nil
|
|
}
|
|
return now.Add(dur), nil
|
|
}
|
|
|
|
func parseComplexDuration(s string) (time.Duration, error) {
|
|
var total time.Duration
|
|
re := regexp.MustCompile(`(\d+)([smhdwMY])`)
|
|
matches := re.FindAllStringSubmatch(s, -1)
|
|
|
|
if matches == nil {
|
|
return 0, errors.Wrap(ErrInvalidDuration, fmt.Errorf("%s", s))
|
|
}
|
|
|
|
for _, match := range matches {
|
|
val, _ := strconv.Atoi(match[1])
|
|
unit := match[2]
|
|
|
|
var d time.Duration
|
|
switch unit {
|
|
case "s":
|
|
d = time.Duration(val) * time.Second
|
|
case "m":
|
|
d = time.Duration(val) * time.Minute
|
|
case "h":
|
|
d = time.Duration(val) * time.Hour
|
|
case "d":
|
|
d = time.Duration(val) * 24 * time.Hour
|
|
case "w":
|
|
d = time.Duration(val) * 7 * 24 * time.Hour
|
|
default:
|
|
return 0, errors.Wrap(ErrUnsupportedUnit, fmt.Errorf("%s", unit))
|
|
}
|
|
|
|
total += d
|
|
}
|
|
return total, nil
|
|
}
|