diff --git a/CHANGELOG.md b/CHANGELOG.md index e49658c..db0144f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # go-utils + +## [v1.27.0] - 2022-09-22 +### New Features +- add GetCronNextAt + + ## [v1.26.0] - 2022-09-21 ### New Features @@ -52,11 +58,11 @@ - fix marshal issue on gorm.DeletedAt empty value ([#32](https://github.com/kumparan/kumnats/issues/32)) - -## [v1.20.0] - 2022-03-11 - ## [v.1.20.0] - 2022-03-11 + + +## [v1.20.0] - 2022-03-11 ### New Features - add constraint size gql directive ([#30](https://github.com/kumparan/kumnats/issues/30)) @@ -154,11 +160,11 @@ - add money formatter for multiple currencies ([#13](https://github.com/kumparan/kumnats/issues/13)) - -## [v1.7.1] - 2020-12-10 - ## [v1.8.0] - 2020-12-10 + + +## [v1.7.1] - 2020-12-10 ### New Features - add formatter for indonesian money and date @@ -223,7 +229,8 @@ - init go-utils -[Unreleased]: https://github.com/kumparan/kumnats/compare/v1.26.0...HEAD +[Unreleased]: https://github.com/kumparan/kumnats/compare/v1.27.0...HEAD +[v1.27.0]: https://github.com/kumparan/kumnats/compare/v1.26.0...v1.27.0 [v1.26.0]: https://github.com/kumparan/kumnats/compare/v1.25.1...v1.26.0 [v1.25.1]: https://github.com/kumparan/kumnats/compare/v1.25.0...v1.25.1 [v1.25.0]: https://github.com/kumparan/kumnats/compare/v1.24.0...v1.25.0 @@ -231,9 +238,9 @@ [v1.23.0]: https://github.com/kumparan/kumnats/compare/v1.22.0...v1.23.0 [v1.22.0]: https://github.com/kumparan/kumnats/compare/v1.21.0...v1.22.0 [v1.21.0]: https://github.com/kumparan/kumnats/compare/v1.20.1...v1.21.0 -[v1.20.1]: https://github.com/kumparan/kumnats/compare/v1.20.0...v1.20.1 -[v1.20.0]: https://github.com/kumparan/kumnats/compare/v.1.20.0...v1.20.0 -[v.1.20.0]: https://github.com/kumparan/kumnats/compare/v1.19.3...v.1.20.0 +[v1.20.1]: https://github.com/kumparan/kumnats/compare/v.1.20.0...v1.20.1 +[v.1.20.0]: https://github.com/kumparan/kumnats/compare/v1.20.0...v.1.20.0 +[v1.20.0]: https://github.com/kumparan/kumnats/compare/v1.19.3...v1.20.0 [v1.19.3]: https://github.com/kumparan/kumnats/compare/v1.19.2...v1.19.3 [v1.19.2]: https://github.com/kumparan/kumnats/compare/v1.19.1...v1.19.2 [v1.19.1]: https://github.com/kumparan/kumnats/compare/v1.19.0...v1.19.1 @@ -249,9 +256,9 @@ [v1.12.0]: https://github.com/kumparan/kumnats/compare/v1.11.0...v1.12.0 [v1.11.0]: https://github.com/kumparan/kumnats/compare/v1.10.0...v1.11.0 [v1.10.0]: https://github.com/kumparan/kumnats/compare/v1.9.0...v1.10.0 -[v1.9.0]: https://github.com/kumparan/kumnats/compare/v1.7.1...v1.9.0 -[v1.7.1]: https://github.com/kumparan/kumnats/compare/v1.8.0...v1.7.1 -[v1.8.0]: https://github.com/kumparan/kumnats/compare/v1.7.0...v1.8.0 +[v1.9.0]: https://github.com/kumparan/kumnats/compare/v1.8.0...v1.9.0 +[v1.8.0]: https://github.com/kumparan/kumnats/compare/v1.7.1...v1.8.0 +[v1.7.1]: https://github.com/kumparan/kumnats/compare/v1.7.0...v1.7.1 [v1.7.0]: https://github.com/kumparan/kumnats/compare/v1.6.0...v1.7.0 [v1.6.0]: https://github.com/kumparan/kumnats/compare/v1.5.0...v1.6.0 [v1.5.0]: https://github.com/kumparan/kumnats/compare/v1.4.0...v1.5.0 diff --git a/cron.go b/cron.go new file mode 100644 index 0000000..3a325bb --- /dev/null +++ b/cron.go @@ -0,0 +1,23 @@ +package utils + +import ( + "time" + + "github.com/robfig/cron/v3" +) + +var cronNextAtTimeFormat = "2006-01-02T15:04:05" + +// GetCronNextAt supports +// - Standard crontab specs, e.g. "* * * * ?" +// - Descriptors, e.g. "@midnight", "@every 1h30m" +// if cron parsing error then return current time +func GetCronNextAt(cronTab string) string { + now := time.Now() + var schedule, err = cron.ParseStandard(cronTab) + if err != nil { + return now.Format(cronNextAtTimeFormat) + } + + return schedule.Next(now).Format(cronNextAtTimeFormat) +} diff --git a/cron_test.go b/cron_test.go new file mode 100644 index 0000000..41899e7 --- /dev/null +++ b/cron_test.go @@ -0,0 +1,22 @@ +package utils + +import ( + "testing" + "time" + + "github.com/agiledragon/gomonkey" + "github.com/stretchr/testify/assert" +) + +func TestCron_GetCronNextAt(t *testing.T) { + now, _ := time.Parse(time.RFC3339, "2010-01-02T15:00:00Z") + patch := gomonkey.ApplyFunc(time.Now, func() time.Time { return now }) + defer patch.Reset() + + assert.Equal(t, now.Format(cronNextAtTimeFormat), GetCronNextAt("* ngaco * cron nya ")) // wrong cron tab,return current time as next at + assert.Equal(t, now.Add(1*time.Hour).Format(cronNextAtTimeFormat), GetCronNextAt("@hourly")) + assert.Equal(t, now.Add(1*time.Minute).Format(cronNextAtTimeFormat), GetCronNextAt("*/1 * * * *")) + assert.Equal(t, now.Add(1*time.Hour).Format(cronNextAtTimeFormat), GetCronNextAt("0 */1 * * *")) // every hour + assert.Equal(t, now.Add(2*time.Hour).Format(cronNextAtTimeFormat), GetCronNextAt("0 17 */1 * *")) // every 17:00 + assert.Equal(t, now.Add(30*time.Second).Format(cronNextAtTimeFormat), GetCronNextAt("@every 30s")) +} diff --git a/go.mod b/go.mod index 3f6e2dd..4bf6484 100644 --- a/go.mod +++ b/go.mod @@ -4,11 +4,13 @@ go 1.18 require ( github.com/99designs/gqlgen v0.14.0 + github.com/agiledragon/gomonkey v2.0.2+incompatible github.com/getsentry/sentry-go v0.11.0 github.com/goodsign/monday v1.0.0 github.com/graph-gophers/graphql-go v1.4.0 github.com/leekchan/accounting v0.3.1 github.com/microcosm-cc/bluemonday v1.0.19 + github.com/robfig/cron/v3 v3.0.1 github.com/shopspring/decimal v1.2.0 github.com/sirupsen/logrus v1.8.1 github.com/stretchr/testify v1.7.1 diff --git a/go.sum b/go.sum index cb710e8..289b366 100644 --- a/go.sum +++ b/go.sum @@ -7,6 +7,8 @@ github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3 github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= +github.com/agiledragon/gomonkey v2.0.2+incompatible h1:eXKi9/piiC3cjJD1658mEE2o3NjkJ5vDLgYjCQu0Xlw= +github.com/agiledragon/gomonkey v2.0.2+incompatible/go.mod h1:2NGfXu1a80LLr2cmWXGBDaHEjb1idR6+FVlX5T3D9hw= github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= github.com/agnivade/levenshtein v1.1.0/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= @@ -128,8 +130,6 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= -github.com/microcosm-cc/bluemonday v1.0.18 h1:6HcxvXDAi3ARt3slx6nTesbvorIc3QeTzBNRvWktHBo= -github.com/microcosm-cc/bluemonday v1.0.18/go.mod h1:Z0r70sCuXHig8YpBzCc5eGHAap2K7e/u082ZUpDRRqM= github.com/microcosm-cc/bluemonday v1.0.19 h1:OI7hoF5FY4pFz2VA//RN8TfM0YJ2dJcl4P4APrCWy6c= github.com/microcosm-cc/bluemonday v1.0.19/go.mod h1:QNzV2UbLK2/53oIIwTOyLUSABMkjZ4tqiyC1g/DyqxE= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= @@ -159,6 +159,8 @@ github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= +github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -254,10 +256,8 @@ golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da h1:b3NXsE2LusjYGGjL5bxEVZZORm/YEFFrWFjR8eFrw/c= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=