using extrenal lib for next date

This commit is contained in:
Radu Ioan Fericean
2014-09-30 19:05:41 +03:00
parent 5e5aa78579
commit b669f2e8ac
7 changed files with 168 additions and 20 deletions

View File

@@ -25,6 +25,7 @@ import (
"time"
"github.com/cgrates/cgrates/utils"
"github.com/gorhill/cronexpr"
)
const (
@@ -46,6 +47,29 @@ type ActionTiming struct {
type ActionPlan []*ActionTiming
func (at *ActionTiming) GetNextStartTime(now time.Time) (t time.Time) {
if !at.stCache.IsZero() {
return at.stCache
}
i := at.Timing
if i == nil || i.Timing == nil {
return
}
// Normalize
if i.Timing.StartTime == "" {
i.Timing.StartTime = "00:00:00"
}
if len(i.Timing.Years) > 0 && len(i.Timing.Months) == 0 {
i.Timing.Months = append(i.Timing.Months, 1)
}
if len(i.Timing.Months) > 0 && len(i.Timing.MonthDays) == 0 {
i.Timing.MonthDays = append(i.Timing.MonthDays, 1)
}
at.stCache = cronexpr.MustParse(i.Timing.CronString()).Next(now)
return at.stCache
}
// To be deleted after the above solution proves reliable
func (at *ActionTiming) GetNextStartTimeOld(now time.Time) (t time.Time) {
if !at.stCache.IsZero() {
return at.stCache
}

View File

@@ -69,9 +69,9 @@ func TestActionTimingOnlyHour(t *testing.T) {
}
func TestActionTimingHourYear(t *testing.T) {
at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{Years: utils.Years{2012}, StartTime: "10:01:00"}}}
at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{Years: utils.Years{2022}, StartTime: "10:01:00"}}}
st := at.GetNextStartTime(referenceDate)
expected := time.Date(2012, 1, 1, 10, 1, 0, 0, time.Local)
expected := time.Date(2022, 1, 1, 10, 1, 0, 0, time.Local)
if !st.Equal(expected) {
t.Errorf("Expected %v was %v", expected, st)
}
@@ -245,9 +245,9 @@ func TestActionTimingOnlyYears(t *testing.T) {
}
func TestActionTimingPast(t *testing.T) {
at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{Years: utils.Years{2013}}}}
at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{Years: utils.Years{2023}}}}
st := at.GetNextStartTime(referenceDate)
expected := time.Date(2013, 1, 1, 0, 0, 0, 0, time.Local)
expected := time.Date(2023, 1, 1, 0, 0, 0, 0, time.Local)
if !st.Equal(expected) {
t.Errorf("Expected %v was %v", expected, st)
}
@@ -411,7 +411,7 @@ func TestActionTimingLogFunction(t *testing.T) {
func TestActionTimingPriotityListSortByWeight(t *testing.T) {
at1 := &ActionTiming{Timing: &RateInterval{
Timing: &RITiming{
Years: utils.Years{2100},
Years: utils.Years{2020},
Months: utils.Months{time.January, time.February, time.March, time.April, time.May, time.June, time.July, time.August, time.September, time.October, time.November, time.December},
MonthDays: utils.MonthDays{1},
StartTime: "00:00:00",
@@ -420,7 +420,7 @@ func TestActionTimingPriotityListSortByWeight(t *testing.T) {
}}
at2 := &ActionTiming{Timing: &RateInterval{
Timing: &RITiming{
Years: utils.Years{2100},
Years: utils.Years{2020},
Months: utils.Months{time.January, time.February, time.March, time.April, time.May, time.June, time.July, time.August, time.September, time.October, time.November, time.December},
MonthDays: utils.MonthDays{2},
StartTime: "00:00:00",

View File

@@ -532,28 +532,28 @@ func TestLoadRatingPlans(t *testing.T) {
expected := &RatingPlan{
Id: "STANDARD",
Timings: map[string]*RITiming{
"14ae6e41": &RITiming{
"4c954a4f": &RITiming{
Years: utils.Years{},
Months: utils.Months{},
MonthDays: utils.MonthDays{},
WeekDays: utils.WeekDays{1, 2, 3, 4, 5},
StartTime: "00:00:00",
},
"9a6f8e32": &RITiming{
"4d593287": &RITiming{
Years: utils.Years{},
Months: utils.Months{},
MonthDays: utils.MonthDays{},
WeekDays: utils.WeekDays{1, 2, 3, 4, 5},
StartTime: "18:00:00",
},
"7181e535": &RITiming{
"a60bfb13": &RITiming{
Years: utils.Years{},
Months: utils.Months{},
MonthDays: utils.MonthDays{},
WeekDays: utils.WeekDays{time.Saturday, time.Sunday},
StartTime: "00:00:00",
},
"96c78ff5": &RITiming{
"30eab300": &RITiming{
Years: utils.Years{},
Months: utils.Months{},
MonthDays: utils.MonthDays{},
@@ -618,48 +618,48 @@ func TestLoadRatingPlans(t *testing.T) {
DestinationRates: map[string]RPRateList{
"GERMANY": []*RPRate{
&RPRate{
Timing: "14ae6e41",
Timing: "4c954a4f",
Rating: "822a5aef",
Weight: 10,
},
&RPRate{
Timing: "9a6f8e32",
Timing: "4d593287",
Rating: "4a25c533",
Weight: 10,
},
&RPRate{
Timing: "7181e535",
Timing: "a60bfb13",
Rating: "4a25c533",
Weight: 10,
},
},
"GERMANY_O2": []*RPRate{
&RPRate{
Timing: "14ae6e41",
Timing: "4c954a4f",
Rating: "4a25c533",
Weight: 10,
},
&RPRate{
Timing: "9a6f8e32",
Timing: "4d593287",
Rating: "b05c5f6b",
Weight: 10,
},
&RPRate{
Timing: "7181e535",
Timing: "a60bfb13",
Rating: "b05c5f6b",
Weight: 10,
},
},
"GERMANY_PREMIUM": []*RPRate{
&RPRate{
Timing: "14ae6e41",
Timing: "4c954a4f",
Rating: "4a25c533",
Weight: 10,
},
},
"URG": []*RPRate{
&RPRate{
Timing: "96c78ff5",
Timing: "30eab300",
Rating: "9f49ef8e",
Weight: 20,
},
@@ -667,7 +667,7 @@ func TestLoadRatingPlans(t *testing.T) {
},
}
if !reflect.DeepEqual(rplan, expected) {
t.Errorf("Error loading destination rate timing: %+v", rplan.DestinationRates["URG"][0])
t.Errorf("Error loading destination rate timing: %+v", rplan.DestinationRates["GERMANY_O2"][0])
}
}

View File

@@ -45,6 +45,74 @@ type RITiming struct {
MonthDays utils.MonthDays
WeekDays utils.WeekDays
StartTime, EndTime string // ##:##:## format
cronString string
}
func (rit *RITiming) CronString() string {
if rit.cronString != "" {
return rit.cronString
}
var sec, min, hour, monthday, month, weekday, year string
if len(rit.StartTime) == 0 {
hour, min, sec = "*", "*", "*"
} else {
hms := strings.Split(rit.StartTime, ":")
if len(hms) != 3 {
hour, min, sec = "*", "*", "*"
}
hour, min, sec = hms[0], hms[1], hms[2]
if strings.HasPrefix(hour, "0") {
hour = hour[1:]
}
if strings.HasPrefix(min, "0") {
min = min[1:]
}
if strings.HasPrefix(sec, "0") {
sec = sec[1:]
}
}
if len(rit.MonthDays) == 0 {
monthday = "*"
} else {
for i, md := range rit.MonthDays {
if i > 0 {
monthday += ","
}
monthday += strconv.Itoa(md)
}
}
if len(rit.Months) == 0 {
month = "*"
} else {
for i, md := range rit.Months {
if i > 0 {
month += ","
}
month += strconv.Itoa(int(md))
}
}
if len(rit.WeekDays) == 0 {
weekday = "*"
} else {
for i, md := range rit.WeekDays {
if i > 0 {
weekday += ","
}
weekday += strconv.Itoa(int(md))
}
}
if len(rit.Years) == 0 {
year = "*"
} else {
for i, md := range rit.Years {
if i > 0 {
year += ","
}
year += strconv.Itoa(int(md))
}
}
rit.cronString = fmt.Sprintf("%s %s %s %s %s %s %s", sec, min, hour, monthday, month, weekday, year)
return rit.cronString
}
func (rit *RITiming) Stringify() string {

View File

@@ -19,9 +19,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
package engine
import (
"github.com/cgrates/cgrates/utils"
"testing"
"time"
"github.com/cgrates/cgrates/utils"
)
func TestRateIntervalSimpleContains(t *testing.T) {
@@ -283,6 +284,59 @@ func TestRateStrigyfy(t *testing.T) {
}
}
func TestRateIntervalCronAll(t *testing.T) {
rit := &RITiming{
Years: utils.Years{2012},
Months: utils.Months{time.February},
MonthDays: utils.MonthDays{1},
WeekDays: []time.Weekday{time.Sunday},
StartTime: "14:30:00",
}
expected := "0 30 14 1 2 0 2012"
cron := rit.CronString()
if cron != expected {
t.Errorf("Expected %s was %s", expected, cron)
}
}
func TestRateIntervalCronMultiple(t *testing.T) {
rit := &RITiming{
Years: utils.Years{2012, 2014},
Months: utils.Months{time.February, time.January},
MonthDays: utils.MonthDays{15, 16},
WeekDays: []time.Weekday{time.Sunday, time.Monday},
StartTime: "14:30:00",
}
expected := "0 30 14 15,16 2,1 0,1 2012,2014"
cron := rit.CronString()
if cron != expected {
t.Errorf("Expected %s was %s", expected, cron)
}
}
func TestRateIntervalCronStar(t *testing.T) {
rit := &RITiming{
StartTime: "*:30:00",
}
expected := "0 30 * * * * *"
cron := rit.CronString()
if cron != expected {
t.Errorf("Expected %s was %s", expected, cron)
}
}
func TestRateIntervalCronEmpty(t *testing.T) {
rit := &RITiming{}
expected := "* * * * * * *"
cron := rit.CronString()
if cron != expected {
t.Errorf("Expected %s was %s", expected, cron)
}
}
/*********************************Benchmarks**************************************/
func BenchmarkRateIntervalContainsDate(b *testing.B) {

View File

@@ -14,6 +14,7 @@ libs = ('code.google.com/p/goconf/conf',
'github.com/hoisie/redis'
'github.com/howeyc/fsnotify',
'github.com/jinzhu/gorm',
'github.com/gorhill/cronexpr',
)
if __name__ == "__main__":

View File

@@ -11,3 +11,4 @@ go get -u -v github.com/howeyc/fsnotify
go get -u -v github.com/cgrates/liner
go get -u -v github.com/cgrates/rpcclient
go get -u -v github.com/jinzhu/gorm
go get -u -v github.com/gorhill/cronexpr