diff --git a/internal/infra/models/plan.go b/internal/infra/models/plan.go index 84aaa79..38d98fc 100644 --- a/internal/infra/models/plan.go +++ b/internal/infra/models/plan.go @@ -41,8 +41,8 @@ const ( type PlanStatus uint8 const ( - PlanStatusEnabled PlanStatus = 0 // 启用计划 - PlanStatusDisabled PlanStatus = 1 // 禁用计划 + PlanStatusDisabled PlanStatus = 0 // 禁用计划 + PlanStatusEnabled PlanStatus = 1 // 启用计划 PlanStatusStopeed PlanStatus = 2 // 执行完毕 ) diff --git a/internal/infra/utils/time.go b/internal/infra/utils/time.go index fed5705..b66e39a 100644 --- a/internal/infra/utils/time.go +++ b/internal/infra/utils/time.go @@ -6,12 +6,18 @@ import ( "github.com/robfig/cron/v3" ) +// cronParserWithSeconds 是一个自定义的 cron 解析器,它包含了秒字段。 +// 这允许解析6部分的 cron 表达式(带秒),并处理 '?' 通配符。 +var cronParserWithSeconds = cron.NewParser( + cron.Second | cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow | cron.Descriptor, +) + // GetNextCronTime 根据传入的 Cron 表达式计算下一次执行的时间。 -// 它使用兼容大多数 Cron 实现的标准解析器。 +// 它使用一个支持秒级精度和'?'通配符的解析器。 // 如果 Cron 表达式无效,它将返回一个错误。 func GetNextCronTime(cronExpression string) (time.Time, error) { - // cron.ParseStandard() 返回一个支持标准5位或6位(带秒)格式的解析器。 - schedule, err := cron.ParseStandard(cronExpression) + // 使用自定义的解析器来解析表达式 + schedule, err := cronParserWithSeconds.Parse(cronExpression) if err != nil { return time.Time{}, err // 返回零值时间和错误 } diff --git a/internal/infra/utils/time_test.go b/internal/infra/utils/time_test.go new file mode 100644 index 0000000..dd645e8 --- /dev/null +++ b/internal/infra/utils/time_test.go @@ -0,0 +1,69 @@ +package utils_test + +import ( + "testing" + "time" + + "git.huangwc.com/pig/pig-farm-controller/internal/infra/utils" +) + +func TestGetNextCronTime(t *testing.T) { + tests := []struct { + name string + expression string + expectError bool + }{ + { + name: "标准5位cron表达式", + expression: "0 15 10 * * *", + expectError: false, + }, + { + name: "带秒的6位cron表达式", + expression: "30 0 15 10 * *", + expectError: false, + }, + { + name: "带'?'通配符的cron表达式", + expression: "0 15 10 * * ?", + expectError: false, + }, + { + name: "带秒和'?'通配符的cron表达式", + expression: "30 0 15 10 * ?", + expectError: false, + }, + { + name: "无效的cron表达式", + expression: "invalid-cron", + expectError: true, + }, + { + name: "每秒执行", + expression: "* * * * * *", + expectError: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + nextTime, err := utils.GetNextCronTime(tt.expression) + if tt.expectError { + if err == nil { + t.Errorf("期望得到一个错误,但没有得到") + } + } else { + if err != nil { + t.Errorf("不期望得到错误,但得到了: %v", err) + } + if nextTime.IsZero() { + t.Errorf("期望得到一个有效的下一次执行时间,但得到了零值时间") + } + // 可以在这里添加更具体的断言来验证时间是否在预期范围内 + if !nextTime.After(time.Now()) { + t.Errorf("期望的下一次执行时间 %v 应该在当前时间之后", nextTime) + } + } + }) + } +}