timetask.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. package p
  2. import (
  3. "strings"
  4. "time"
  5. util "app.yhyue.com/moapp/jybase/common"
  6. "github.com/donnie4w/go-logger/logger"
  7. )
  8. var VarTimeTask = &timeTask{}
  9. type timeTask struct {
  10. }
  11. /* 定时任务,一轮一轮执行,不停歇
  12. * @param msg 打印输出的信息
  13. * @param start 开始时间
  14. * @param end 结束时间
  15. * @param duration 定时任务时间间隔
  16. * @param runRightNow 是否立即执行
  17. * @param dayFirst 是否是今天第一次执行
  18. * @param nowRunHours 这些小时,任务不执行
  19. * @param f 需要执行的方法逻辑
  20. */
  21. func (t *timeTask) RunInTimeLoop(msg, start, end string, duration int64, runRightNow, dayFirst bool, nowRunHours []int, f func()) {
  22. if !dayFirst && !t.IsInTimeSection(start, end) {
  23. logger.Info(msg, "当前时间不在", start, end, "范围内,不执行")
  24. return
  25. }
  26. if runRightNow {
  27. isRun := true
  28. hour := time.Now().Hour()
  29. for _, v := range nowRunHours {
  30. if v == hour {
  31. isRun = false
  32. break
  33. }
  34. }
  35. if isRun {
  36. f()
  37. }
  38. }
  39. d := time.Duration(duration) * time.Minute
  40. logger.Info(msg, "start runInTimeLoop after", d)
  41. time.AfterFunc(d, func() {
  42. t.RunInTimeLoop(msg, start, end, duration, true, false, nowRunHours, f)
  43. })
  44. }
  45. /* 定时任务,在时间区间内一轮一轮执行
  46. * @param msg 打印输出的信息
  47. * @param start 开始时间
  48. * @param end 结束时间
  49. * @param f 需要执行的方法逻辑
  50. */
  51. func (t *timeTask) RunInTimeSection(msg, start, end string, duration int64, f func(dayFirst bool)) {
  52. now := time.Now()
  53. //开始时间
  54. startArr := strings.Split(start, ":")
  55. starttime := time.Date(now.Year(), now.Month(), now.Day(), util.IntAll(startArr[0]), util.IntAll(startArr[1]), 0, 0, time.Local)
  56. var sub time.Duration
  57. if now.Before(starttime) {
  58. sub = starttime.Sub(time.Now())
  59. } else {
  60. if t.IsInTimeSection(start, end) {
  61. if duration > 0 {
  62. go t.RunInTimeLoop(msg, start, end, duration, true, false, nil, func() {
  63. f(false)
  64. })
  65. } else {
  66. go f(false)
  67. }
  68. } else {
  69. logger.Info(msg, "当前时间不在", start, end, "范围内,不执行")
  70. }
  71. sub = starttime.AddDate(0, 0, 1).Sub(time.Now())
  72. }
  73. logger.Info("start runInTimeSection after", sub)
  74. timer := time.NewTimer(sub)
  75. for {
  76. select {
  77. case <-timer.C:
  78. timer.Reset(time.Hour * 24)
  79. if t.IsInTimeSection(start, end) {
  80. if duration > 0 {
  81. go t.RunInTimeLoop(msg, start, end, duration, true, false, nil, func() {
  82. f(true)
  83. })
  84. } else {
  85. go f(true)
  86. }
  87. } else {
  88. logger.Info(msg, "当前时间不在", start, end, "范围内,不执行")
  89. }
  90. }
  91. }
  92. }
  93. /* 是否在时间区间内
  94. * @param start 开始时间
  95. * @param end 结束时间
  96. */
  97. func (t *timeTask) IsInTimeSection(start, end string) bool {
  98. if start == "" || end == "" {
  99. return true
  100. }
  101. now := time.Now()
  102. start_time := strings.Split(start, ":")
  103. starttime := time.Date(now.Year(), now.Month(), now.Day(), util.IntAll(start_time[0]), util.IntAll(start_time[1]), 0, 0, time.Local)
  104. //
  105. end_time := strings.Split(end, ":")
  106. endtime := time.Date(now.Year(), now.Month(), now.Day(), util.IntAll(end_time[0]), util.IntAll(end_time[1]), 0, 0, time.Local)
  107. return now.After(starttime) && now.Before(endtime)
  108. }
  109. //
  110. func (t *timeTask) Week() (int64, int64) {
  111. endDate := time.Now().AddDate(0, 0, -WeekNum[time.Now().Weekday().String()])
  112. endDate = time.Date(endDate.Year(), endDate.Month(), endDate.Day(), 0, 0, 0, 0, time.Local)
  113. startDate := endDate.AddDate(0, 0, -6)
  114. return startDate.Unix(), endDate.Unix()
  115. }
  116. //
  117. func (t *timeTask) Month() (int64, int64) {
  118. now := time.Now().AddDate(0, -1, 0)
  119. startDate := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, time.Local)
  120. endDate := startDate.AddDate(0, 1, -1)
  121. return startDate.Unix(), endDate.Unix()
  122. }
  123. //每小时整点执行任务
  124. func (t *timeTask) RunEveryHour(runRightNow bool, f func()) {
  125. if runRightNow {
  126. go f()
  127. }
  128. now := time.Now()
  129. nextHour := time.Date(now.Year(), now.Month(), now.Day(), now.Hour()+1, 0, 0, 0, time.Local)
  130. sub := nextHour.Sub(now)
  131. logger.Info("start runEveryHour after", sub)
  132. ticker := time.NewTicker(sub)
  133. for {
  134. select {
  135. case <-ticker.C:
  136. go f()
  137. logger.Info("start runEveryHour after", time.Hour)
  138. ticker.Reset(time.Hour)
  139. }
  140. }
  141. }