commit ccb860d1964213c79ab870845193b673e086bf06 Author: dtapps Date: Fri Dec 22 13:12:58 2023 +0800 init diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..c56c479 --- /dev/null +++ b/.drone.yml @@ -0,0 +1,17 @@ +kind: pipeline +type: docker +name: clone + +steps: + - name: Test + image: golang:1.18 + commands: + - go env -w GO111MODULE=on + - go env -w GOPROXY=https://goproxy.cn,direct + - go test -v ./... + - name: Benchmark + image: golang:1.18 + commands: + - go env -w GO111MODULE=on + - go env -w GOPROXY=https://goproxy.cn,direct + - go test -bench=. -benchmem \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..760d251 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +.env +.git +.svn +.idea +.vscode +*.log +gomod.sh +*_test.go +/vendor/ \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..ff84bbf --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 李光春 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..7a8991c --- /dev/null +++ b/README.md @@ -0,0 +1,17 @@ +

+Golang rocron +

+ +📦 Golang rocron + +[comment]: <> (go) +[![godoc](https://pkg.go.dev/badge/go.dtapp.net/rocron?status.svg)](https://pkg.go.dev/go.dtapp.net/rocron) +[![goproxy.cn](https://goproxy.cn/stats/go.dtapp.net/rocron/badges/download-count.svg)](https://goproxy.cn/stats/go.dtapp.net/rocron) +[![goreportcard.com](https://goreportcard.com/badge/go.dtapp.net/rocron)](https://goreportcard.com/report/go.dtapp.net/rocron) +[![deps.dev](https://img.shields.io/badge/deps-go-red.svg)](https://deps.dev/go/go.dtapp.net%2Frocron) + +#### 安装 + +```shell +go get -v -u go.dtapp.net/rocron@v1.0.0 +``` diff --git a/crontab.go b/crontab.go new file mode 100644 index 0000000..272bb6b --- /dev/null +++ b/crontab.go @@ -0,0 +1,123 @@ +package rocron + +import ( + "fmt" +) + +var ( + YearlySpec = "0 0 0 1 1 *" + YearlyExplain = "每年一次,1 月 1 日午夜执行一次" + AnnuallySpec = "0 0 0 1 1 *" + AnnuallyExplain = "每年一次,1 月 1 日午夜执行一次" + MonthlySpec = "0 0 0 1 * *" + MonthlyExplain = "每月执行,午夜,月初执行一次" + WeeklySpec = "0 0 0 * * 0" + WeeklyExplain = "每周执行,周六和周日之间的午夜执行一次" + DailySpec = "0 0 0 * * *" + DailyExplain = "每天午夜执行一次" + MidnightSpec = "0 0 0 * * *" + MidnightExplain = "每天午夜执行一次" + HourlySpec = "0 0 * * * *" + HourlyExplain = "每小时运行,每小时开始执行一次" +) + +/* +* +┌─────────────second 范围 (0 - 60) +│ ┌───────────── min (0 - 59) +│ │ ┌────────────── hour (0 - 23) +│ │ │ ┌─────────────── day of month (1 - 31) +│ │ │ │ ┌──────────────── month (1 - 12) +│ │ │ │ │ ┌───────────────── day of week (0 - 6) (0 to 6 are Sunday to +│ │ │ │ │ │ Saturday) +│ │ │ │ │ │ +│ │ │ │ │ │ +* * * * * * +*/ +const ( + secondsSpec = "*/%d * * * * *" + minutesSpec = "%d */%d * * * *" + hoursSpec = "%d %d */%d * * *" + daySpec = "%d %d %d */%d * *" + daysSpec = "%d %d %d %s * *" +) + +// GetSecondSpec 每隔秒 +func GetSecondSpec(seconds int) string { + seconds = filterSeconds(seconds) + return fmt.Sprintf(secondsSpec, seconds) +} + +// GetSecondExplain 每隔秒 +func GetSecondExplain(seconds int) string { + seconds = filterSeconds(seconds) + return fmt.Sprintf("每隔 %d 秒执行一次", seconds) +} + +// GetMinuteSpec 每隔分钟 +func GetMinuteSpec(minutes, seconds int) string { + minutes = filterMinutes(minutes) + seconds = filterSeconds(seconds) + return fmt.Sprintf(minutesSpec, seconds, minutes) +} + +// GetMinuteExplain 每隔分钟 +func GetMinuteExplain(minutes, seconds int) string { + minutes = filterMinutes(minutes) + seconds = filterSeconds(seconds) + if seconds <= 0 { + return fmt.Sprintf("每隔 %d 分钟执行一次", minutes) + } + return fmt.Sprintf("每隔 %d 分钟 %d 秒执行一次", minutes, seconds) +} + +// GetHourSpec 每隔小时 +func GetHourSpec(hours, minutes, seconds int) string { + hours = filterHours(hours) + minutes = filterMinutes(minutes) + seconds = filterSeconds(seconds) + return fmt.Sprintf(hoursSpec, seconds, minutes, hours) +} + +// GetHourExplain 每隔小时 +func GetHourExplain(hours, minutes, seconds int) string { + hours = filterHours(hours) + minutes = filterMinutes(minutes) + seconds = filterSeconds(seconds) + if seconds <= 0 { + if minutes <= 0 { + return fmt.Sprintf("每隔 %d 小时执行一次", hours) + } + return fmt.Sprintf("每隔 %d 小时 %d 分执行一次", hours, minutes) + } + return fmt.Sprintf("每隔 %d 小时 %d 分 %d 秒执行一次", hours, minutes, seconds) +} + +// GetDaySpec 天 +func GetDaySpec(day, hours, minutes, seconds int) string { + day = filterDays(day) + hours = filterHours(hours) + minutes = filterMinutes(minutes) + seconds = filterSeconds(seconds) + return fmt.Sprintf(daySpec, seconds, minutes, hours, day) + //days := concatenateStrings(day) + //return fmt.Sprintf(daysSpec, seconds, minutes, hours, days) +} + +// GetDayExplain 天 +func GetDayExplain(days, hours, minutes, seconds int) string { + days = filterDays(days) + hours = filterHours(hours) + minutes = filterMinutes(minutes) + seconds = filterSeconds(seconds) + if seconds <= 0 { + if minutes <= 0 { + if hours <= 0 { + return fmt.Sprintf("每隔 %d 天执行一次", days) + } + return fmt.Sprintf("每隔 %d 天 %d 时执行一次", days, hours) + } + return fmt.Sprintf("每隔 %d 天 %d 时 %d 分执行一次", days, hours, minutes) + } + return fmt.Sprintf("每隔 %d 天 %d 时 %d 分 %d 秒执行一次", days, hours, minutes, seconds) +} diff --git a/filter.go b/filter.go new file mode 100644 index 0000000..a93ff25 --- /dev/null +++ b/filter.go @@ -0,0 +1,41 @@ +package rocron + +func filterSeconds(seconds int) int { + if seconds <= 0 { + return 0 + } + if seconds > 60 { + return 60 + } + return seconds +} + +func filterMinutes(minutes int) int { + if minutes <= 0 { + return 0 + } + if minutes > 59 { + return 59 + } + return minutes +} + +func filterHours(hours int) int { + if hours <= 0 { + return 0 + } + if hours > 23 { + return 23 + } + return hours +} + +func filterDays(days int) int { + if days <= 0 { + return 1 + } + if days > 31 { + return 31 + } + return days +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..f9163a3 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module go.dtapp.net/rocron + +go 1.21 diff --git a/tool.go b/tool.go new file mode 100644 index 0000000..b92a905 --- /dev/null +++ b/tool.go @@ -0,0 +1,32 @@ +package rocron + +import "fmt" + +func concatenateStrings(day int) string { + var result string + if day > 1 { + result += "1" + } + for i := 1; i <= 31; i++ { + if isDivisibleBy(i, day) { + if len(result) > 0 { + result += "," + } + result += fmt.Sprintf("%d", i) + } + } + + return result +} + +func isDivisibleBy(num, divisor int) bool { + return num%divisor == 0 +} + +func removeFirstTwoChars(str string) string { + if len(str) > 2 { + return str[2:] + } + + return "" +} diff --git a/version.go b/version.go new file mode 100644 index 0000000..f7ee677 --- /dev/null +++ b/version.go @@ -0,0 +1,5 @@ +package rocron + +const ( + Version = "1.0.0" +)