timetask.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. package p
  2. import (
  3. "strings"
  4. "time"
  5. util "app.yhyue.com/moapp/jybase/common"
  6. "app.yhyue.com/moapp/jybase/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. func (t *timeTask) RunInSecondTimeLoop(msg, start, end string, duration int64, runRightNow, dayFirst bool, nowRunHours []int, f func()) {
  47. if !dayFirst && !t.IsInTimeSection(start, end) {
  48. logger.Info(msg, "当前时间不在", start, end, "范围内,不执行")
  49. return
  50. }
  51. if runRightNow {
  52. isRun := true
  53. hour := time.Now().Hour()
  54. for _, v := range nowRunHours {
  55. if v == hour {
  56. isRun = false
  57. break
  58. }
  59. }
  60. if isRun {
  61. f()
  62. }
  63. }
  64. d := time.Duration(duration) * time.Second
  65. logger.Info(msg, "start runInTimeLoop after", d)
  66. time.AfterFunc(d, func() {
  67. t.RunInSecondTimeLoop(msg, start, end, duration, true, false, nowRunHours, f)
  68. })
  69. }
  70. /* 定时任务,在时间区间内一轮一轮执行
  71. * @param msg 打印输出的信息
  72. * @param start 开始时间
  73. * @param end 结束时间
  74. * @param f 需要执行的方法逻辑
  75. */
  76. func (t *timeTask) RunInTimeSection(msg, start, end string, duration int64, f func(dayFirst bool)) {
  77. now := time.Now()
  78. //开始时间
  79. startArr := strings.Split(start, ":")
  80. starttime := time.Date(now.Year(), now.Month(), now.Day(), util.IntAll(startArr[0]), util.IntAll(startArr[1]), 0, 0, time.Local)
  81. var sub time.Duration
  82. if now.Before(starttime) {
  83. sub = starttime.Sub(time.Now())
  84. } else {
  85. if t.IsInTimeSection(start, end) {
  86. if duration > 0 {
  87. go t.RunInTimeLoop(msg, start, end, duration, true, false, nil, func() {
  88. f(false)
  89. })
  90. } else {
  91. go f(false)
  92. }
  93. } else {
  94. logger.Info(msg, "当前时间不在", start, end, "范围内,不执行")
  95. }
  96. sub = starttime.AddDate(0, 0, 1).Sub(time.Now())
  97. }
  98. logger.Info("start runInTimeSection after", sub)
  99. timer := time.NewTimer(sub)
  100. for {
  101. select {
  102. case <-timer.C:
  103. timer.Reset(time.Hour * 24)
  104. if t.IsInTimeSection(start, end) {
  105. if duration > 0 {
  106. go t.RunInTimeLoop(msg, start, end, duration, true, false, nil, func() {
  107. f(true)
  108. })
  109. } else {
  110. go f(true)
  111. }
  112. } else {
  113. logger.Info(msg, "当前时间不在", start, end, "范围内,不执行")
  114. }
  115. }
  116. }
  117. }
  118. /* 是否在时间区间内
  119. * @param start 开始时间
  120. * @param end 结束时间
  121. */
  122. func (t *timeTask) IsInTimeSection(start, end string) bool {
  123. if start == "" || end == "" {
  124. return true
  125. }
  126. now := time.Now()
  127. start_time := strings.Split(start, ":")
  128. starttime := time.Date(now.Year(), now.Month(), now.Day(), util.IntAll(start_time[0]), util.IntAll(start_time[1]), 0, 0, time.Local)
  129. //
  130. end_time := strings.Split(end, ":")
  131. endtime := time.Date(now.Year(), now.Month(), now.Day(), util.IntAll(end_time[0]), util.IntAll(end_time[1]), 0, 0, time.Local)
  132. return now.After(starttime) && now.Before(endtime)
  133. }
  134. func (t *timeTask) Week() (int64, int64) {
  135. endDate := time.Now().AddDate(0, 0, -WeekNum[time.Now().Weekday().String()])
  136. endDate = time.Date(endDate.Year(), endDate.Month(), endDate.Day(), 0, 0, 0, 0, time.Local)
  137. startDate := endDate.AddDate(0, 0, -6)
  138. return startDate.Unix(), endDate.Unix()
  139. }
  140. func (t *timeTask) Month() (int64, int64) {
  141. now := time.Now().AddDate(0, -1, 0)
  142. startDate := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, time.Local)
  143. endDate := startDate.AddDate(0, 1, -1)
  144. return startDate.Unix(), endDate.Unix()
  145. }
  146. // 每小时整点执行任务
  147. func (t *timeTask) RunEveryHour(runRightNow bool, f func()) {
  148. if runRightNow {
  149. go f()
  150. }
  151. now := time.Now()
  152. nextHour := time.Date(now.Year(), now.Month(), now.Day(), now.Hour()+1, 0, 0, 0, time.Local)
  153. sub := nextHour.Sub(now)
  154. logger.Info("start runEveryHour after", sub)
  155. ticker := time.NewTicker(sub)
  156. for {
  157. select {
  158. case <-ticker.C:
  159. go f()
  160. logger.Info("start runEveryHour after", time.Hour)
  161. ticker.Reset(time.Hour)
  162. }
  163. }
  164. }