diff --git a/packages/debian/changelog b/packages/debian/changelog index cc5d229da..9acf0b999 100644 --- a/packages/debian/changelog +++ b/packages/debian/changelog @@ -5,6 +5,8 @@ cgrates (0.10.2~dev) UNRELEASED; urgency=medium * [Server] Corectly log the server listen error * [ERs] Add *none EventReader type * [ERs] Renamed *default reader folders + * [General] Added *mo+extraDuration time support (e.g. *mo+1h will + be time.Now() + 1 month + 1 hour) -- DanB Tue, 12 May 2020 13:08:15 +0300 @@ -19,7 +21,7 @@ cgrates (0.10.1) UNRELEASED; urgency=medium * [Templates] Added new dataconvertor: *ip2hex * [AgentRequest] Added support for *group type and correctly overwrite the values in case of *variable - * [EventReader] Correctly populate ConcurrentRequest from config in + * [ERs] Correctly populate ConcurrentRequest from config in EventReader * [SupplierS] In case of missing usage from Event use 1 minute as default value @@ -34,7 +36,7 @@ cgrates (0.10.1) UNRELEASED; urgency=medium * [AgentRequest] Improved NavigableMap * [AgentRequest] FieldAsInterface return Data instead of NMItem * [SupplierS] Allow multiple suppliers with the same ID - * [Engine] Skip caching is limit is 0 + * [Engine] Skip caching if limit is 0 * [CacheS] Avoid long recaching -- DanB Wed, 5 May 2020 15:22:59 +0200 diff --git a/utils/coreutils.go b/utils/coreutils.go index 7fcada9a7..f7bf6eb98 100644 --- a/utils/coreutils.go +++ b/utils/coreutils.go @@ -176,6 +176,15 @@ func Round(x float64, prec int, method string) float64 { return rounder / pow } +func getAddDuration(tmStr string) (addDur time.Duration, err error) { + eDurIdx := strings.Index(tmStr, "+") + if eDurIdx == -1 { + return + } + return time.ParseDuration(tmStr[eDurIdx+1:]) +} + +// ParseTimeDetectLayout returns the time from string func ParseTimeDetectLayout(tmStr string, timezone string) (time.Time, error) { tmStr = strings.TrimSpace(tmStr) var nilTime time.Time @@ -197,14 +206,18 @@ func ParseTimeDetectLayout(tmStr string, timezone string) (time.Time, error) { return time.Now().AddDate(1, 0, 0), nil // add one year case strings.HasPrefix(tmStr, "*month_end"): expDate := GetEndOfMonth(time.Now()) - if eDurIdx := strings.Index(tmStr, "+"); eDurIdx != -1 { - var extraDur time.Duration - if extraDur, err = time.ParseDuration(tmStr[eDurIdx+1:]); err != nil { - return nilTime, err - } - expDate = expDate.Add(extraDur) + extraDur, err := getAddDuration(tmStr) + if err != nil { + return nilTime, err } + expDate = expDate.Add(extraDur) return expDate, nil + case strings.HasPrefix(tmStr, "*mo"): // add one month and extra duration + extraDur, err := getAddDuration(tmStr) + if err != nil { + return nilTime, err + } + return time.Now().AddDate(0, 1, 0).Add(extraDur), nil case astTimestamp.MatchString(tmStr): return time.Parse("2006-01-02T15:04:05.999999999-0700", tmStr) case rfc3339Rule.MatchString(tmStr): @@ -265,7 +278,7 @@ func ParseTimeDetectLayout(tmStr string, timezone string) (time.Time, error) { return nilTime, errors.New("Unsupported time format") } -// returns a number equal or larger than the amount that exactly +// RoundDuration returns a number equal or larger than the amount that exactly // is divisible to whole func RoundDuration(whole, amount time.Duration) time.Duration { a, w := float64(amount), float64(whole) diff --git a/utils/coreutils_test.go b/utils/coreutils_test.go index cf64b2332..40e3978d8 100644 --- a/utils/coreutils_test.go +++ b/utils/coreutils_test.go @@ -391,6 +391,18 @@ func TestParseTimeDetectLayout(t *testing.T) { } else if expected.Sub(date).Seconds() > 1 { t.Errorf("received: %+v", date) } + expected = time.Now().AddDate(0, 1, 0) + if date, err := ParseTimeDetectLayout("*mo", ""); err != nil { + t.Error(err) + } else if expected.Sub(date).Seconds() > 1 { + t.Errorf("received: %+v", date) + } + expected = time.Now().AddDate(0, 1, 0).Add(time.Hour + 2*time.Minute) + if date, err := ParseTimeDetectLayout("*mo+1h2m", ""); err != nil { + t.Error(err) + } else if expected.Sub(date).Seconds() > 1 { + t.Errorf("received: %+v", date) + } expected = time.Now().AddDate(1, 0, 0) if date, err := ParseTimeDetectLayout("*yearly", ""); err != nil { t.Error(err) @@ -416,6 +428,12 @@ func TestParseTimeDetectLayout(t *testing.T) { t.Errorf("Expecting nilTime, received: %+v", date) } + if date, err := ParseTimeDetectLayout("*mo+xyz", ""); err == nil { + t.Error("Expecting error 'time: invalid time duration', received: nil") + } else if date != nilTime { + t.Errorf("Expecting nilTime, received: %+v", date) + } + date, err = ParseTimeDetectLayout("2013-07-30T19:33:10Z", "") expected = time.Date(2013, 7, 30, 19, 33, 10, 0, time.UTC) if err != nil || !date.Equal(expected) {