2021-01-21 18:55:34 +08:00
|
|
|
|
package utils
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
2022-10-03 19:28:03 +08:00
|
|
|
|
"fmt"
|
2021-01-21 18:55:34 +08:00
|
|
|
|
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
2021-11-08 20:52:15 +08:00
|
|
|
|
"github.com/iwind/TeaGo/lists"
|
2021-01-21 18:55:34 +08:00
|
|
|
|
"github.com/iwind/TeaGo/types"
|
|
|
|
|
|
timeutil "github.com/iwind/TeaGo/utils/time"
|
|
|
|
|
|
"regexp"
|
|
|
|
|
|
"time"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2022-07-05 20:08:58 +08:00
|
|
|
|
// 分钟时间点
|
2022-10-03 19:28:03 +08:00
|
|
|
|
type timeDayMinute struct {
|
2022-07-05 20:08:58 +08:00
|
|
|
|
Day string
|
|
|
|
|
|
Minute string
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 分钟时间范围
|
2022-10-03 19:28:03 +08:00
|
|
|
|
type timeDayMinuteRange struct {
|
2022-07-05 20:08:58 +08:00
|
|
|
|
Day string
|
|
|
|
|
|
MinuteFrom string
|
|
|
|
|
|
MinuteTo string
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-11-08 20:52:15 +08:00
|
|
|
|
// RangeDays 计算日期之间的所有日期,格式为YYYYMMDD
|
2021-01-21 18:55:34 +08:00
|
|
|
|
func RangeDays(dayFrom string, dayTo string) ([]string, error) {
|
|
|
|
|
|
ok, err := regexp.MatchString(`^\d{8}$`, dayFrom)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
if !ok {
|
|
|
|
|
|
return nil, errors.New("invalid 'dayFrom'")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ok, err = regexp.MatchString(`^\d{8}$`, dayTo)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
if !ok {
|
|
|
|
|
|
return nil, errors.New("invalid 'dayTo'")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if dayFrom > dayTo {
|
|
|
|
|
|
dayFrom, dayTo = dayTo, dayFrom
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 不能超过N天
|
|
|
|
|
|
maxDays := 100 - 1 // -1 是去掉默认加入的dayFrom
|
|
|
|
|
|
result := []string{dayFrom}
|
|
|
|
|
|
|
|
|
|
|
|
year := types.Int(dayFrom[:4])
|
|
|
|
|
|
month := types.Int(dayFrom[4:6])
|
|
|
|
|
|
day := types.Int(dayFrom[6:])
|
|
|
|
|
|
t := time.Date(year, time.Month(month), day, 0, 0, 0, 0, time.Local)
|
|
|
|
|
|
for {
|
|
|
|
|
|
t = t.AddDate(0, 0, 1)
|
|
|
|
|
|
newDay := timeutil.Format("Ymd", t)
|
|
|
|
|
|
if newDay <= dayTo {
|
|
|
|
|
|
result = append(result, newDay)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
maxDays--
|
|
|
|
|
|
if maxDays <= 0 {
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return result, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-11-08 20:52:15 +08:00
|
|
|
|
// RangeMonths 计算日期之间的所有月份,格式为YYYYMM
|
|
|
|
|
|
func RangeMonths(dayFrom string, dayTo string) ([]string, error) {
|
|
|
|
|
|
ok, err := regexp.MatchString(`^\d{8}$`, dayFrom)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
if !ok {
|
|
|
|
|
|
return nil, errors.New("invalid 'dayFrom'")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ok, err = regexp.MatchString(`^\d{8}$`, dayTo)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
if !ok {
|
|
|
|
|
|
return nil, errors.New("invalid 'dayTo'")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if dayFrom > dayTo {
|
|
|
|
|
|
dayFrom, dayTo = dayTo, dayFrom
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-07-05 20:08:58 +08:00
|
|
|
|
var result = []string{dayFrom[:6]}
|
2021-11-08 20:52:15 +08:00
|
|
|
|
|
2022-07-05 20:08:58 +08:00
|
|
|
|
var year = types.Int(dayFrom[:4])
|
|
|
|
|
|
var month = types.Int(dayFrom[4:6])
|
|
|
|
|
|
var day = types.Int(dayFrom[6:])
|
|
|
|
|
|
var t = time.Date(year, time.Month(month), day, 0, 0, 0, 0, time.Local)
|
2021-11-08 20:52:15 +08:00
|
|
|
|
for {
|
|
|
|
|
|
t = t.AddDate(0, 0, 20)
|
2022-07-05 20:08:58 +08:00
|
|
|
|
var newDay = timeutil.Format("Ymd", t)
|
2021-11-08 20:52:15 +08:00
|
|
|
|
if newDay <= dayTo {
|
|
|
|
|
|
var monthString = newDay[:6]
|
|
|
|
|
|
if !lists.ContainsString(result, monthString) {
|
|
|
|
|
|
result = append(result, monthString)
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var endMonth = dayTo[:6]
|
|
|
|
|
|
if !lists.ContainsString(result, endMonth) {
|
|
|
|
|
|
result = append(result, endMonth)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return result, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// RangeHours 计算小时之间的所有小时,格式为YYYYMMDDHH
|
2021-01-21 18:55:34 +08:00
|
|
|
|
func RangeHours(hourFrom string, hourTo string) ([]string, error) {
|
|
|
|
|
|
ok, err := regexp.MatchString(`^\d{10}$`, hourFrom)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
if !ok {
|
|
|
|
|
|
return nil, errors.New("invalid 'hourFrom'")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ok, err = regexp.MatchString(`^\d{10}$`, hourTo)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
if !ok {
|
|
|
|
|
|
return nil, errors.New("invalid 'hourTo'")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if hourFrom > hourTo {
|
|
|
|
|
|
hourFrom, hourTo = hourTo, hourFrom
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 不能超过N天
|
2022-07-05 20:08:58 +08:00
|
|
|
|
var maxHours = 100 - 1 // -1 是去掉默认加入的dayFrom
|
|
|
|
|
|
var result = []string{hourFrom}
|
|
|
|
|
|
|
|
|
|
|
|
var year = types.Int(hourFrom[:4])
|
|
|
|
|
|
var month = types.Int(hourFrom[4:6])
|
|
|
|
|
|
var day = types.Int(hourFrom[6:8])
|
|
|
|
|
|
var hour = types.Int(hourFrom[8:])
|
|
|
|
|
|
var t = time.Date(year, time.Month(month), day, hour, 0, 0, 0, time.Local)
|
2021-01-21 18:55:34 +08:00
|
|
|
|
for {
|
|
|
|
|
|
t = t.Add(1 * time.Hour)
|
2022-07-05 20:08:58 +08:00
|
|
|
|
var newHour = timeutil.Format("YmdH", t)
|
2021-01-21 18:55:34 +08:00
|
|
|
|
if newHour <= hourTo {
|
|
|
|
|
|
result = append(result, newHour)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
maxHours--
|
|
|
|
|
|
if maxHours <= 0 {
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return result, nil
|
|
|
|
|
|
}
|
2022-07-05 20:08:58 +08:00
|
|
|
|
|
|
|
|
|
|
// RangeMinutes 计算若干个时间点,返回结果为 [ [day1, minute1], [day2, minute2] ... ]
|
2022-10-03 19:28:03 +08:00
|
|
|
|
func RangeMinutes(toTime time.Time, count int, everyMinutes int32) []timeDayMinute {
|
2022-07-05 20:08:58 +08:00
|
|
|
|
var everySeconds = everyMinutes * 60
|
|
|
|
|
|
if everySeconds <= 0 {
|
|
|
|
|
|
everySeconds = 300
|
|
|
|
|
|
}
|
2022-10-03 19:28:03 +08:00
|
|
|
|
var result = []timeDayMinute{}
|
|
|
|
|
|
var fromTime = time.Unix(toTime.Unix()-int64(everySeconds)*int64(count-1), 0)
|
2022-07-05 20:08:58 +08:00
|
|
|
|
for {
|
2022-10-03 19:28:03 +08:00
|
|
|
|
var timestamp = fromTime.Unix() / int64(everySeconds) * int64(everySeconds)
|
|
|
|
|
|
result = append(result, timeDayMinute{
|
2022-07-05 20:08:58 +08:00
|
|
|
|
Day: timeutil.FormatTime("Ymd", timestamp),
|
|
|
|
|
|
Minute: timeutil.FormatTime("Hi", timestamp),
|
|
|
|
|
|
})
|
2022-10-03 19:28:03 +08:00
|
|
|
|
fromTime = time.Unix(fromTime.Unix()+int64(everySeconds), 0)
|
2022-07-05 20:08:58 +08:00
|
|
|
|
|
|
|
|
|
|
count--
|
|
|
|
|
|
if count <= 0 {
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return result
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// GroupMinuteRanges 将时间点分组
|
2022-10-03 19:28:03 +08:00
|
|
|
|
func GroupMinuteRanges(minutes []timeDayMinute) []timeDayMinuteRange {
|
|
|
|
|
|
var result = []*timeDayMinuteRange{}
|
2022-07-05 20:08:58 +08:00
|
|
|
|
var lastDay = ""
|
2022-10-03 19:28:03 +08:00
|
|
|
|
var lastRange *timeDayMinuteRange
|
2022-07-05 20:08:58 +08:00
|
|
|
|
for _, minute := range minutes {
|
|
|
|
|
|
if minute.Day != lastDay {
|
|
|
|
|
|
lastDay = minute.Day
|
2022-10-03 19:28:03 +08:00
|
|
|
|
lastRange = &timeDayMinuteRange{
|
2022-07-05 20:08:58 +08:00
|
|
|
|
Day: minute.Day,
|
|
|
|
|
|
MinuteFrom: minute.Minute,
|
|
|
|
|
|
MinuteTo: minute.Minute,
|
|
|
|
|
|
}
|
|
|
|
|
|
result = append(result, lastRange)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
if lastRange != nil {
|
|
|
|
|
|
lastRange.MinuteTo = minute.Minute
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-10-03 19:28:03 +08:00
|
|
|
|
var finalResult = []timeDayMinuteRange{}
|
2022-07-05 20:08:58 +08:00
|
|
|
|
for _, minutePtr := range result {
|
|
|
|
|
|
finalResult = append(finalResult, *minutePtr)
|
|
|
|
|
|
}
|
|
|
|
|
|
return finalResult
|
|
|
|
|
|
}
|
2022-10-03 19:28:03 +08:00
|
|
|
|
|
|
|
|
|
|
// RangeTimes 计算时间点
|
|
|
|
|
|
func RangeTimes(timeFrom string, timeTo string, everyMinutes int32) (result []string, err error) {
|
|
|
|
|
|
if everyMinutes <= 0 {
|
|
|
|
|
|
return nil, errors.New("invalid 'everyMinutes'")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var reg = regexp.MustCompile(`^\d{4}$`)
|
|
|
|
|
|
if !reg.MatchString(timeFrom) {
|
|
|
|
|
|
return nil, errors.New("invalid timeFrom '" + timeFrom + "'")
|
|
|
|
|
|
}
|
|
|
|
|
|
if !reg.MatchString(timeTo) {
|
|
|
|
|
|
return nil, errors.New("invalid timeTo '" + timeTo + "'")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if timeFrom > timeTo {
|
|
|
|
|
|
// swap
|
|
|
|
|
|
timeFrom, timeTo = timeTo, timeFrom
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var everyMinutesInt = int(everyMinutes)
|
|
|
|
|
|
|
|
|
|
|
|
var fromHour = types.Int(timeFrom[:2])
|
|
|
|
|
|
var fromMinute = types.Int(timeFrom[2:])
|
|
|
|
|
|
var toHour = types.Int(timeTo[:2])
|
|
|
|
|
|
var toMinute = types.Int(timeTo[2:])
|
|
|
|
|
|
|
|
|
|
|
|
if fromMinute%everyMinutesInt == 0 {
|
|
|
|
|
|
result = append(result, timeFrom)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for {
|
|
|
|
|
|
fromMinute += everyMinutesInt
|
|
|
|
|
|
if fromMinute > 59 {
|
|
|
|
|
|
fromHour += fromMinute / 60
|
|
|
|
|
|
fromMinute = fromMinute % 60
|
|
|
|
|
|
}
|
|
|
|
|
|
if fromHour > toHour || (fromHour == toHour && fromMinute > toMinute) {
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
|
|
|
|
|
result = append(result, fmt.Sprintf("%02d%02d", fromHour, fromMinute))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Range24HourTimes 计算24小时时间点
|
|
|
|
|
|
// 从 00:00 - 23:59
|
|
|
|
|
|
func Range24HourTimes(everyMinutes int32) ([]string, error) {
|
|
|
|
|
|
if everyMinutes <= 0 {
|
|
|
|
|
|
return nil, errors.New("invalid 'everyMinutes'")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return RangeTimes("0000", "2359", everyMinutes)
|
|
|
|
|
|
}
|