mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
Revise GetNextStartTime method
This commit is contained in:
committed by
Dan Christian Bogos
parent
b66e9bb31f
commit
fd156c4838
@@ -117,35 +117,48 @@ func getDayOrEndOfMonth(day int, t1 time.Time) int {
|
||||
return day
|
||||
}
|
||||
|
||||
func (at *ActionTiming) GetNextStartTime(t1 time.Time) (t time.Time) {
|
||||
func (at *ActionTiming) GetNextStartTime(refTime time.Time) time.Time {
|
||||
if !at.stCache.IsZero() {
|
||||
return at.stCache
|
||||
}
|
||||
i := at.Timing
|
||||
if i == nil || i.Timing == nil {
|
||||
return
|
||||
rateIvl := at.Timing
|
||||
if rateIvl == nil || rateIvl.Timing == nil {
|
||||
return time.Time{}
|
||||
}
|
||||
// Normalize
|
||||
if i.Timing.StartTime == "" {
|
||||
i.Timing.StartTime = "00:00:00"
|
||||
if rateIvl.Timing.StartTime == "" {
|
||||
rateIvl.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(rateIvl.Timing.Years) > 0 && len(rateIvl.Timing.Months) == 0 {
|
||||
rateIvl.Timing.Months = append(rateIvl.Timing.Months, 1)
|
||||
}
|
||||
if len(i.Timing.Months) > 0 && len(i.Timing.MonthDays) == 0 {
|
||||
i.Timing.MonthDays = append(i.Timing.MonthDays, 1)
|
||||
if len(rateIvl.Timing.Months) > 0 && len(rateIvl.Timing.MonthDays) == 0 {
|
||||
rateIvl.Timing.MonthDays = append(rateIvl.Timing.MonthDays, 1)
|
||||
}
|
||||
at.stCache = cronexpr.MustParse(i.Timing.CronString()).Next(t1)
|
||||
if i.Timing.ID == utils.MetaMonthlyEstimated {
|
||||
// substract a month from at.stCache only if we skip 2 months
|
||||
// or we skip a month because mentioned MonthDay is after the last day of the current month
|
||||
if at.stCache.Month() == t1.Month()+2 ||
|
||||
(utils.GetEndOfMonth(t1).Day() < at.Timing.Timing.MonthDays[0] &&
|
||||
at.stCache.Month() == t1.Month()+1) {
|
||||
lastDay := utils.GetEndOfMonth(at.stCache).Day()
|
||||
// only change the time if the new one is after t1
|
||||
if tmp := at.stCache.AddDate(0, 0, -lastDay); tmp.After(t1) {
|
||||
at.stCache = tmp
|
||||
at.stCache = cronexpr.MustParse(rateIvl.Timing.CronString()).Next(refTime)
|
||||
if rateIvl.Timing.ID == utils.MetaMonthlyEstimated {
|
||||
// When target day doesn't exist in a month, fall back to that month's last day
|
||||
// instead of skipping to next occurrence.
|
||||
currentMonth := refTime.Month()
|
||||
targetMonthDay := rateIvl.Timing.MonthDays[0]
|
||||
oneMonthSkip := utils.GetEndOfMonth(refTime).Day() < targetMonthDay &&
|
||||
at.stCache.Month() == currentMonth+1
|
||||
twoMonthSkip := at.stCache.Month() == currentMonth+2
|
||||
if oneMonthSkip || twoMonthSkip {
|
||||
daysToSubtract := utils.GetEndOfMonth(at.stCache).Day()
|
||||
|
||||
// When transitioning from Jan to Feb, subtract the
|
||||
// actual desired day instead of Mar's last day.
|
||||
// This fixes cases like:
|
||||
// - Jan 29 -> Mar 29 (should be Feb 28 in non-leap years)
|
||||
// - Jan 30 -> Mar 30 (should be Feb 28/29)
|
||||
if currentMonth == time.January {
|
||||
daysToSubtract = targetMonthDay
|
||||
}
|
||||
|
||||
adjustedTime := at.stCache.AddDate(0, 0, -daysToSubtract)
|
||||
if adjustedTime.After(refTime) {
|
||||
at.stCache = adjustedTime
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -516,20 +516,19 @@ func TestActionTimingGetNextStartTimesMonthlyEstimated(t *testing.T) {
|
||||
},
|
||||
expected: time.Date(2021, 1, 31, 14, 25, 0, 0, time.UTC),
|
||||
},
|
||||
// {
|
||||
// name: "Non-Leap Year: January 29 to Feb 28",
|
||||
// t1: time.Date(2021, 1, 29, 0, 0, 0, 0, time.UTC),
|
||||
// at: &ActionTiming{
|
||||
// Timing: &RateInterval{
|
||||
// Timing: &RITiming{
|
||||
// ID: utils.MetaMonthlyEstimated,
|
||||
// MonthDays: utils.MonthDays{29},
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// expected: time.Date(2021, 2, 28, 0, 0, 0, 0, time.UTC),
|
||||
// },
|
||||
|
||||
{
|
||||
name: "Non-Leap Year: January 29 to Feb 28",
|
||||
t1: time.Date(2021, 1, 29, 0, 0, 0, 0, time.UTC),
|
||||
at: &ActionTiming{
|
||||
Timing: &RateInterval{
|
||||
Timing: &RITiming{
|
||||
ID: utils.MetaMonthlyEstimated,
|
||||
MonthDays: utils.MonthDays{29},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: time.Date(2021, 2, 28, 0, 0, 0, 0, time.UTC),
|
||||
},
|
||||
{
|
||||
name: "Non-Leap Year: February 28 to March 28",
|
||||
t1: time.Date(2021, 2, 28, 0, 0, 0, 0, time.UTC),
|
||||
@@ -622,6 +621,77 @@ func TestActionTimingGetNextStartTimesMonthlyEstimated(t *testing.T) {
|
||||
},
|
||||
expected: time.Date(2021, 9, 30, 0, 0, 0, 0, time.UTC),
|
||||
},
|
||||
|
||||
{
|
||||
name: "Non-Leap Year: Jan 29 to Feb 28",
|
||||
t1: time.Date(2021, 1, 29, 0, 0, 0, 0, time.UTC),
|
||||
at: &ActionTiming{
|
||||
Timing: &RateInterval{
|
||||
Timing: &RITiming{
|
||||
ID: utils.MetaMonthlyEstimated,
|
||||
MonthDays: utils.MonthDays{29},
|
||||
StartTime: "00:00:00",
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: time.Date(2021, 2, 28, 0, 0, 0, 0, time.UTC),
|
||||
},
|
||||
{
|
||||
name: "Leap Year: Jan 30 to Feb 29 ",
|
||||
t1: time.Date(2020, 1, 30, 0, 0, 0, 0, time.UTC),
|
||||
at: &ActionTiming{
|
||||
Timing: &RateInterval{
|
||||
Timing: &RITiming{
|
||||
ID: utils.MetaMonthlyEstimated,
|
||||
MonthDays: utils.MonthDays{30},
|
||||
StartTime: "00:00:00",
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: time.Date(2020, 2, 29, 0, 0, 0, 0, time.UTC),
|
||||
},
|
||||
{
|
||||
name: "Non-Leap Year: Jan 30 to Feb 28 ",
|
||||
t1: time.Date(2021, 1, 30, 0, 0, 0, 0, time.UTC),
|
||||
at: &ActionTiming{
|
||||
Timing: &RateInterval{
|
||||
Timing: &RITiming{
|
||||
ID: utils.MetaMonthlyEstimated,
|
||||
MonthDays: utils.MonthDays{30},
|
||||
StartTime: "00:00:00",
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: time.Date(2021, 2, 28, 0, 0, 0, 0, time.UTC),
|
||||
},
|
||||
{
|
||||
name: "Non-Leap Year: Jan 15 to Feb 15 ",
|
||||
t1: time.Date(2021, 1, 15, 0, 0, 0, 0, time.UTC),
|
||||
at: &ActionTiming{
|
||||
Timing: &RateInterval{
|
||||
Timing: &RITiming{
|
||||
ID: utils.MetaMonthlyEstimated,
|
||||
MonthDays: utils.MonthDays{15},
|
||||
StartTime: "00:00:00",
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: time.Date(2021, 2, 15, 0, 0, 0, 0, time.UTC),
|
||||
},
|
||||
{
|
||||
name: "Jan 14 to Jan 15 ",
|
||||
t1: time.Date(2021, 1, 14, 0, 0, 0, 0, time.UTC),
|
||||
at: &ActionTiming{
|
||||
Timing: &RateInterval{
|
||||
Timing: &RITiming{
|
||||
ID: utils.MetaMonthlyEstimated,
|
||||
MonthDays: utils.MonthDays{15},
|
||||
StartTime: "00:00:00",
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: time.Date(2021, 1, 15, 0, 0, 0, 0, time.UTC),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
|
||||
Reference in New Issue
Block a user