From 1014d645309eb1d2aa9ca0ffb1894da818dca3a3 Mon Sep 17 00:00:00 2001 From: lvyitao Date: Thu, 4 Jul 2024 16:51:32 +0800 Subject: [PATCH 1/3] fix():add last day of month match --- spec.go | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/spec.go b/spec.go index fa1e241e..ca369dab 100644 --- a/spec.go +++ b/spec.go @@ -1,6 +1,8 @@ package cron -import "time" +import ( + "time" +) // SpecSchedule specifies a duty cycle (to the second granularity), based on a // traditional crontab specification. It is computed initially and stored as bit sets. @@ -22,7 +24,7 @@ var ( seconds = bounds{0, 59, nil} minutes = bounds{0, 59, nil} hours = bounds{0, 23, nil} - dom = bounds{1, 31, nil} + dom = bounds{1, 32, map[string]uint{"l":32}} months = bounds{1, 12, map[string]uint{ "jan": 1, "feb": 2, @@ -174,13 +176,31 @@ WRAP: return t.In(origLocation) } +func lastDayOfMonth(year int, month time.Month) time.Time { + // 下一个月的第一天 + nextMonth := time.Date(year, month+1, 1, 0, 0, 0, 0, time.UTC) + // 下一个月的第一天减去一天即为当前月的最后一天 + lastDay := nextMonth.AddDate(0, 0, -1) + return lastDay +} + // dayMatches returns true if the schedule's day-of-week and day-of-month // restrictions are satisfied by the given time. func dayMatches(s *SpecSchedule, t time.Time) bool { var ( - domMatch bool = 1< 0 + // 100 10000000000000000000000000000 + domLastDayMatch bool = 1<0 + domMatch bool = 1< 0 dowMatch bool = 1< 0 ) + if domLastDayMatch{ + lastDay := lastDayOfMonth(t.Year(),t.Month()) + if (1<0{ + return true + }else{ + return false + } + } if s.Dom&starBit > 0 || s.Dow&starBit > 0 { return domMatch && dowMatch } From 21724b92ebe386ad33befe2d4305239c4fa42f8b Mon Sep 17 00:00:00 2001 From: lvyitao Date: Fri, 5 Jul 2024 17:10:36 +0800 Subject: [PATCH 2/3] fix():optimize last day of month funtion --- spec.go | 24 ++++++++++++------------ spec_test.go | 1 + 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/spec.go b/spec.go index ca369dab..e4e60d46 100644 --- a/spec.go +++ b/spec.go @@ -186,22 +186,22 @@ func lastDayOfMonth(year int, month time.Month) time.Time { // dayMatches returns true if the schedule's day-of-week and day-of-month // restrictions are satisfied by the given time. +// if they set 32 in day of month it's mean they set last day of month ,so I figure out last day of month dynamically +// use temporary value to compare func dayMatches(s *SpecSchedule, t time.Time) bool { - var ( - // 100 10000000000000000000000000000 - domLastDayMatch bool = 1<0 - domMatch bool = 1< 0 - dowMatch bool = 1< 0 - ) + var domLastDayMatch bool = 1<0 + var domMatch bool + var dowMatch bool = 1< 0 + var tempDom uint64 if domLastDayMatch{ lastDay := lastDayOfMonth(t.Year(),t.Month()) - if (1<0{ - return true - }else{ - return false - } + tempDom = s.Dom | (1<< uint(lastDay.Day())) + domMatch = 1< 0 + }else{ + tempDom = s.Dom + domMatch = 1< 0 } - if s.Dom&starBit > 0 || s.Dow&starBit > 0 { + if tempDom&starBit > 0 || s.Dow&starBit > 0 { return domMatch && dowMatch } return domMatch || dowMatch diff --git a/spec_test.go b/spec_test.go index 1b8a503e..6c2549be 100644 --- a/spec_test.go +++ b/spec_test.go @@ -54,6 +54,7 @@ func TestActivation(t *testing.T) { {"Mon Jul 9 00:00 2012", "* * 1,15 * *", false}, {"Sun Jul 15 00:00 2012", "* * 1,15 * *", true}, {"Sun Jul 15 00:00 2012", "* * */2 * Sun", true}, + {"Wed Jul 31 00:00 2024", "* * L * *", true}, } for _, test := range tests { From 4eaf5c854de30d4f1939d455e2f76203fc15526f Mon Sep 17 00:00:00 2001 From: lvyitao Date: Fri, 5 Jul 2024 17:14:57 +0800 Subject: [PATCH 3/3] doc --- spec.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec.go b/spec.go index e4e60d46..6bf4c757 100644 --- a/spec.go +++ b/spec.go @@ -177,13 +177,13 @@ WRAP: } func lastDayOfMonth(year int, month time.Month) time.Time { - // 下一个月的第一天 + // get first day of next month nextMonth := time.Date(year, month+1, 1, 0, 0, 0, 0, time.UTC) - // 下一个月的第一天减去一天即为当前月的最后一天 lastDay := nextMonth.AddDate(0, 0, -1) return lastDay } + // dayMatches returns true if the schedule's day-of-week and day-of-month // restrictions are satisfied by the given time. // if they set 32 in day of month it's mean they set last day of month ,so I figure out last day of month dynamically