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
+
+[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"
+)