From bbc863f8ab100eebaff42396bb89942084fea6fa Mon Sep 17 00:00:00 2001 From: TeoV Date: Tue, 4 Dec 2018 07:42:25 -0800 Subject: [PATCH] Replace ParseDate with ParseTimeDetectLayout(+ tests) --- apier/v1/apier_it_test.go | 8 +++--- apier/v1/triggers.go | 6 +++-- apier/v2/triggers.go | 2 +- engine/action_plan.go | 7 +++-- engine/action_trigger.go | 4 ++- sessions/data_it_test.go | 2 +- utils/coreutils.go | 56 +++++++++++++-------------------------- utils/coreutils_test.go | 41 ++++++++++------------------ 8 files changed, 50 insertions(+), 76 deletions(-) diff --git a/apier/v1/apier_it_test.go b/apier/v1/apier_it_test.go index 1395da131..a93835eda 100644 --- a/apier/v1/apier_it_test.go +++ b/apier/v1/apier_it_test.go @@ -738,8 +738,8 @@ func TestApierSetRatingProfile(t *testing.T) { } // Make sure rates were loaded for account dan // Test here ResponderGetCost - tStart, _ := utils.ParseDate("2013-08-07T17:30:00Z") - tEnd, _ := utils.ParseDate("2013-08-07T17:31:30Z") + tStart, _ := utils.ParseTimeDetectLayout("2013-08-07T17:30:00Z", "") + tEnd, _ := utils.ParseTimeDetectLayout("2013-08-07T17:31:30Z", "") cd := engine.CallDescriptor{ Direction: "*out", Category: "call", @@ -1357,8 +1357,8 @@ func TestApierGetAccountAfterLoad(t *testing.T) { // Test here ResponderGetCost func TestApierResponderGetCost(t *testing.T) { - tStart, _ := utils.ParseDate("2013-08-07T17:30:00Z") - tEnd, _ := utils.ParseDate("2013-08-07T17:31:30Z") + tStart, _ := utils.ParseTimeDetectLayout("2013-08-07T17:30:00Z", "") + tEnd, _ := utils.ParseTimeDetectLayout("2013-08-07T17:31:30Z", "") cd := engine.CallDescriptor{ Direction: "*out", Category: "call", diff --git a/apier/v1/triggers.go b/apier/v1/triggers.go index 29d9e8a6a..39fd374fd 100644 --- a/apier/v1/triggers.go +++ b/apier/v1/triggers.go @@ -294,7 +294,8 @@ func (self *ApierV1) SetAccountActionTriggers(attr AttrSetAccountActionTriggers, at.Balance.Weight = attr.BalanceWeight } if attr.BalanceExpirationDate != nil { - balanceExpTime, err := utils.ParseDate(*attr.BalanceExpirationDate) + balanceExpTime, err := utils.ParseTimeDetectLayout(*attr.BalanceExpirationDate, + self.Config.GeneralCfg().DefaultTimezone) if err != nil { return 0, err } @@ -488,7 +489,8 @@ func (self *ApierV1) SetActionTrigger(attr AttrSetActionTrigger, reply *string) newAtr.Balance.Weight = attr.BalanceWeight } if attr.BalanceExpirationDate != nil { - balanceExpTime, err := utils.ParseDate(*attr.BalanceExpirationDate) + balanceExpTime, err := utils.ParseTimeDetectLayout(*attr.BalanceExpirationDate, + self.Config.GeneralCfg().DefaultTimezone) if err != nil { *reply = err.Error() return err diff --git a/apier/v2/triggers.go b/apier/v2/triggers.go index 3fa279ab3..4c1bdf529 100644 --- a/apier/v2/triggers.go +++ b/apier/v2/triggers.go @@ -121,7 +121,7 @@ func (attr *AttrSetAccountActionTriggers) UpdateActionTrigger(at *engine.ActionT at.Balance.Weight = attr.BalanceWeight } if attr.BalanceExpirationDate != nil { - balanceExpTime, err := utils.ParseDate(*attr.BalanceExpirationDate) + balanceExpTime, err := utils.ParseTimeDetectLayout(*attr.BalanceExpirationDate, timezone) if err != nil { return false, err } diff --git a/engine/action_plan.go b/engine/action_plan.go index c4b16044b..167033e7b 100644 --- a/engine/action_plan.go +++ b/engine/action_plan.go @@ -23,6 +23,7 @@ import ( "sort" "time" + "github.com/cgrates/cgrates/config" "github.com/cgrates/cgrates/guardian" "github.com/cgrates/cgrates/utils" "github.com/gorhill/cronexpr" @@ -318,7 +319,8 @@ func (at *ActionTiming) Execute(successActions, failedActions chan *Action) (err a.Balance = &BalanceFilter{} } if a.ExpirationString != "" { // if it's *unlimited then it has to be zero time - if expDate, parseErr := utils.ParseDate(a.ExpirationString); parseErr == nil { + if expDate, parseErr := utils.ParseTimeDetectLayout(a.ExpirationString, + config.CgrConfig().GeneralCfg().DefaultTimezone); parseErr == nil { a.Balance.ExpirationDate = &time.Time{} *a.Balance.ExpirationDate = expDate } @@ -355,7 +357,8 @@ func (at *ActionTiming) Execute(successActions, failedActions chan *Action) (err } if len(at.accountIDs) == 0 { // action timing executing without accounts for _, a := range aac { - if expDate, parseErr := utils.ParseDate(a.ExpirationString); (a.Balance == nil || a.Balance.EmptyExpirationDate()) && + if expDate, parseErr := utils.ParseTimeDetectLayout(a.ExpirationString, + config.CgrConfig().GeneralCfg().DefaultTimezone); (a.Balance == nil || a.Balance.EmptyExpirationDate()) && parseErr == nil && !expDate.IsZero() { a.Balance.ExpirationDate = &time.Time{} *a.Balance.ExpirationDate = expDate diff --git a/engine/action_trigger.go b/engine/action_trigger.go index 401921335..caf388583 100644 --- a/engine/action_trigger.go +++ b/engine/action_trigger.go @@ -24,6 +24,7 @@ import ( "sort" "time" + "github.com/cgrates/cgrates/config" "github.com/cgrates/cgrates/utils" ) @@ -81,7 +82,8 @@ func (at *ActionTrigger) Execute(ub *Account) (err error) { a.Balance = &BalanceFilter{} } if a.ExpirationString != "" { // if it's *unlimited then it has to be zero time' - if expDate, parseErr := utils.ParseDate(a.ExpirationString); parseErr == nil { + if expDate, parseErr := utils.ParseTimeDetectLayout(a.ExpirationString, + config.CgrConfig().GeneralCfg().DefaultTimezone); parseErr == nil { a.Balance.ExpirationDate = &time.Time{} *a.Balance.ExpirationDate = expDate } diff --git a/sessions/data_it_test.go b/sessions/data_it_test.go index a877f62b5..d294a4659 100644 --- a/sessions/data_it_test.go +++ b/sessions/data_it_test.go @@ -92,7 +92,7 @@ func TestSMGDataLastUsedData(t *testing.T) { t.Errorf("Expected: %f, received: %f", eAcntVal, acnt.BalanceMap[utils.DATA].GetTotalValue()) } - tStart, _ := utils.ParseDate("2016-01-05T18:31:05Z") + tStart, _ := utils.ParseTimeDetectLayout("2016-01-05T18:31:05Z", "") cd := engine.CallDescriptor{ Direction: "*out", Category: "data", diff --git a/utils/coreutils.go b/utils/coreutils.go index 684be1519..ecafe967f 100644 --- a/utils/coreutils.go +++ b/utils/coreutils.go @@ -177,6 +177,24 @@ func ParseTimeDetectLayout(tmStr string, timezone string) (time.Time, error) { eamonTimestampRule := regexp.MustCompile(`^\d{2}/\d{2}/\d{4}\s{1}\d{2}:\d{2}:\d{2}$`) broadsoftTimestampRule := regexp.MustCompile(`^\d{14}\.\d{3}`) switch { + case tmStr == UNLIMITED || tmStr == "": + // leave it at zero + case tmStr == "*daily": + return time.Now().AddDate(0, 0, 1), nil // add one day + case tmStr == "*monthly": + return time.Now().AddDate(0, 1, 0), nil // add one month + case tmStr == "*yearly": + 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) + } + return expDate, nil case astTimestamp.MatchString(tmStr): return time.Parse("2006-01-02T15:04:05.999999999-0700", tmStr) case rfc3339Rule.MatchString(tmStr): @@ -231,44 +249,6 @@ func ParseTimeDetectLayout(tmStr string, timezone string) (time.Time, error) { return nilTime, errors.New("Unsupported time format") } -func ParseDate(date string) (expDate time.Time, err error) { - date = strings.TrimSpace(date) - switch { - case date == UNLIMITED || date == "": - // leave it at zero - case strings.HasPrefix(date, "+"): - d, err := time.ParseDuration(date[1:]) - if err != nil { - return expDate, err - } - expDate = time.Now().Add(d) - case date == "*daily": - expDate = time.Now().AddDate(0, 0, 1) // add one day - case date == "*monthly": - expDate = time.Now().AddDate(0, 1, 0) // add one month - case date == "*yearly": - expDate = time.Now().AddDate(1, 0, 0) // add one year - case strings.HasPrefix(date, "*month_end"): - expDate = GetEndOfMonth(time.Now()) - if eDurIdx := strings.Index(date, "+"); eDurIdx != -1 { - var extraDur time.Duration - if extraDur, err = time.ParseDuration(date[eDurIdx+1:]); err != nil { - return - } - expDate = expDate.Add(extraDur) - } - case strings.HasSuffix(date, "Z") || strings.Index(date, "+") != -1: // Allow both Z and +hh:mm format - expDate, err = time.Parse(time.RFC3339, date) - default: - unix, err := strconv.ParseInt(date, 10, 64) - if err != nil { - return expDate, err - } - expDate = time.Unix(unix, 0) - } - return -} - // returns a number equal or larger than the amount that exactly // is divisible to whole func RoundDuration(whole, amount time.Duration) time.Duration { diff --git a/utils/coreutils_test.go b/utils/coreutils_test.go index 993ec55b9..d43ac0059 100644 --- a/utils/coreutils_test.go +++ b/utils/coreutils_test.go @@ -257,73 +257,60 @@ func TestParseTimeDetectLayout(t *testing.T) { } else if !tm.Equal(expectedTime) { t.Errorf("Unexpected time parsed: %v, expecting: %v", tm, expectedTime) } -} -func TestParseDateUnix(t *testing.T) { - date, err := ParseDate("1375212790") expected := time.Date(2013, 7, 30, 19, 33, 10, 0, time.UTC) + date, err := ParseTimeDetectLayout("1375212790", "") if err != nil || !date.Equal(expected) { t.Error("error parsing date: ", expected.Sub(date)) } -} -func TestParseDateUnlimited(t *testing.T) { - date, err := ParseDate("*unlimited") + date, err = ParseTimeDetectLayout("*unlimited", "") if err != nil || !date.IsZero() { t.Error("error parsing unlimited date!: ") } -} -func TestParseDateEmpty(t *testing.T) { - date, err := ParseDate("") + date, err = ParseTimeDetectLayout("", "") if err != nil || !date.IsZero() { t.Error("error parsing unlimited date!: ") } -} -func TestParseDatePlus(t *testing.T) { - date, err := ParseDate("+20s") - expected := time.Now() + date, err = ParseTimeDetectLayout("+20s", "") + expected = time.Now() if err != nil || date.Sub(expected).Seconds() > 20 || date.Sub(expected).Seconds() < 19 { t.Error("error parsing date: ", date.Sub(expected).Seconds()) } -} -func TestParseDateMonthly(t *testing.T) { - expected := time.Now().AddDate(0, 1, 0) - if date, err := ParseDate("*monthly"); err != nil { + expected = time.Now().AddDate(0, 1, 0) + if date, err := ParseTimeDetectLayout("*monthly", ""); err != nil { t.Error(err) } else if expected.Sub(date).Seconds() > 1 { t.Errorf("received: %+v", date) } -} -func TestParseDateMonthEnd(t *testing.T) { - expected := GetEndOfMonth(time.Now()) - if date, err := ParseDate("*month_end"); err != nil { + expected = GetEndOfMonth(time.Now()) + if date, err := ParseTimeDetectLayout("*month_end", ""); err != nil { t.Error(err) } else if !date.Equal(expected) { t.Errorf("received: %+v", date) } expected = GetEndOfMonth(time.Now()).Add(time.Hour).Add(2 * time.Minute) - if date, err := ParseDate("*month_end+1h2m"); err != nil { + if date, err := ParseTimeDetectLayout("*month_end+1h2m", ""); err != nil { t.Error(err) } else if !date.Equal(expected) { t.Errorf("expecting: %+v, received: %+v", expected, date) } -} -func TestParseDateRFC3339(t *testing.T) { - date, err := ParseDate("2013-07-30T19:33:10Z") - expected := time.Date(2013, 7, 30, 19, 33, 10, 0, time.UTC) + 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) { t.Error("error parsing date: ", expected.Sub(date)) } - date, err = ParseDate("2016-04-01T02:00:00+02:00") + date, err = ParseTimeDetectLayout("2016-04-01T02:00:00+02:00", "") expected = time.Date(2016, 4, 1, 0, 0, 0, 0, time.UTC) if err != nil || !date.Equal(expected) { t.Errorf("Expecting: %v, received: %v", expected, date) } + } func TestRoundDuration(t *testing.T) {