timer.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435
  1. package util
  2. import (
  3. "time"
  4. )
  5. // 定时器接口
  6. type ServerTimer interface {
  7. //测试是否过期
  8. IsExpired(ms uint64) bool
  9. //重置
  10. Reset(ms uint64, duration time.Duration, fireNow bool)
  11. Cancel()
  12. Canceled() bool
  13. Suspend()
  14. Resume()
  15. IsStart() bool
  16. }
  17. const DATE_FORMAT = "2006-01-02 15:04:05"
  18. const DATE_FORMAT_T = "2006-01-02T15:04:05"
  19. const DATE_FORMAT1 = "2006-01-02"
  20. const DATE_FORMAT2 = "15:04:05"
  21. const DATE_FORMAT3 = "15:04"
  22. var gameLoc *time.Location = nil
  23. func GetLoc() *time.Location {
  24. if gameLoc == nil {
  25. loc, err := time.LoadLocation("Asia/Shanghai")
  26. if err != nil {
  27. gameLoc = time.Local
  28. } else {
  29. gameLoc = loc
  30. }
  31. }
  32. return gameLoc
  33. }
  34. // return ms
  35. func GetCurrentTime() uint64 {
  36. t1 := GetCurrentTimeNow()
  37. return uint64(t1.UnixNano() / 1e6)
  38. }
  39. func GetCurrentTimeNow() time.Time {
  40. loc := GetLoc()
  41. t1 := time.Now()
  42. return t1.In(loc)
  43. }
  44. func GetTimeMilliseconds() uint64 {
  45. return GetCurrentTime()
  46. }
  47. func GetTimeSeconds() int64 {
  48. return GetCurrentTimeNow().Unix()
  49. }
  50. func GetTimeByStr(timeStr string) time.Time {
  51. tempTime, _ := time.ParseInLocation(DATE_FORMAT, timeStr, GetLoc())
  52. return tempTime
  53. }
  54. func GetTimeByUint64(uTime uint64) time.Time {
  55. timeS := int64(uTime / 1000)
  56. timeMS := int64(uTime % 1000)
  57. return time.Unix(timeS, timeMS).In(GetLoc())
  58. }
  59. func GetTimeByUint32(uTime uint32) time.Time {
  60. return time.Unix(int64(uTime), 0).In(GetLoc())
  61. }
  62. func GetHourByTime(uTime uint64) time.Time {
  63. loc := GetLoc()
  64. if uTime <= 0 {
  65. tempTimeStr := GetCurrentTimeNow().Format(DATE_FORMAT2)
  66. tempTime, _ := time.ParseInLocation(DATE_FORMAT2, tempTimeStr, loc)
  67. return tempTime
  68. } else {
  69. tempTimeStr := GetTimeByUint64(uTime).Format(DATE_FORMAT2)
  70. tempTime, _ := time.ParseInLocation(DATE_FORMAT2, tempTimeStr, loc)
  71. return tempTime
  72. }
  73. }
  74. func GetHourByTimeStr(timeStr string) string {
  75. loc := GetLoc()
  76. tempTime, _ := time.ParseInLocation(DATE_FORMAT, timeStr, loc)
  77. tempTime1 := tempTime.Format(DATE_FORMAT2)
  78. return tempTime1
  79. }
  80. func GetHourByTimeStr1(timeStr string) time.Time {
  81. loc := GetLoc()
  82. hTime, _ := time.ParseInLocation(DATE_FORMAT2, timeStr, loc)
  83. return hTime
  84. }
  85. func GetDayByTimeStr(timeStr string) string {
  86. loc := GetLoc()
  87. sTime, _ := time.ParseInLocation(DATE_FORMAT, timeStr, loc)
  88. return sTime.Format(DATE_FORMAT1)
  89. }
  90. func GetDayByTimeStr1(timeStr string) time.Time {
  91. loc := GetLoc()
  92. dTime, _ := time.ParseInLocation(DATE_FORMAT1, timeStr, loc)
  93. return dTime
  94. }
  95. func GetDayByTimeStr2(timeMs uint64) time.Time {
  96. loc := GetLoc()
  97. tempTimeStr := GetTimeByUint64(timeMs).Format(DATE_FORMAT1)
  98. tempTime, _ := time.ParseInLocation(DATE_FORMAT1, tempTimeStr, loc)
  99. return tempTime
  100. }
  101. func GetDayAndHourByTimeStr(timeStr string) (string, string) {
  102. loc := GetLoc()
  103. tempTime, _ := time.ParseInLocation(DATE_FORMAT, timeStr, loc)
  104. hourStr := tempTime.Format(DATE_FORMAT2)
  105. dayStr := tempTime.Format(DATE_FORMAT1)
  106. return dayStr, hourStr
  107. }
  108. func GetDayAndHourByTime(timeStr string) (time.Time, time.Time) {
  109. loc := GetLoc()
  110. tempTime, _ := time.ParseInLocation(DATE_FORMAT, timeStr, loc)
  111. dayStr := tempTime.Format(DATE_FORMAT1)
  112. d, _ := time.ParseInLocation(DATE_FORMAT1, dayStr, loc)
  113. hourStr := tempTime.Format(DATE_FORMAT2)
  114. h, _ := time.ParseInLocation(DATE_FORMAT2, hourStr, loc)
  115. return d, h
  116. }
  117. // 获取最近一天5点更新时间(结束时间戳)
  118. func GetLatest5Hour() uint64 {
  119. loc := GetLoc()
  120. nowTime := GetCurrentTimeNow()
  121. if nowTime.Hour() < 5 {
  122. dayTimeStr := nowTime.Format(DATE_FORMAT1)
  123. tempDayTime, _ := time.ParseInLocation(DATE_FORMAT1, dayTimeStr, loc)
  124. tempDayTime = tempDayTime.Add(time.Hour * 5)
  125. return uint64(tempDayTime.UnixNano() / 1e6)
  126. } else {
  127. dayTimeStr := nowTime.Format(DATE_FORMAT1)
  128. tempDayTime, _ := time.ParseInLocation(DATE_FORMAT1, dayTimeStr, loc)
  129. tempDayTime = tempDayTime.Add(time.Hour * 24)
  130. dayTimeStr = tempDayTime.Format(DATE_FORMAT1)
  131. tempDayTime, _ = time.ParseInLocation(DATE_FORMAT1, dayTimeStr, loc)
  132. tempDayTime = tempDayTime.Add(time.Hour * 5)
  133. return uint64(tempDayTime.UnixNano() / 1e6)
  134. }
  135. }
  136. // 获取最近周一5点更新时间(结束时间戳)
  137. func GetLatestWeek5Hour(ms uint64) uint64 {
  138. loc := GetLoc()
  139. nowTime := GetCurrentTimeNow()
  140. if ms > 0 {
  141. nowTime = GetTimeByUint64(ms)
  142. }
  143. curWeekDay := nowTime.Weekday()
  144. if curWeekDay == 0 {
  145. curWeekDay = 7
  146. }
  147. delDay := 7 - curWeekDay + 1
  148. if curWeekDay == 1 {
  149. if nowTime.Hour() >= 5 {
  150. delDay = 7
  151. } else {
  152. delDay = 0
  153. }
  154. }
  155. nowTime = nowTime.AddDate(0, 0, int(delDay))
  156. dayTimeStr := nowTime.Format(DATE_FORMAT1)
  157. tempDayTime, _ := time.ParseInLocation(DATE_FORMAT1, dayTimeStr, loc)
  158. tempDayTime = tempDayTime.Add(time.Hour * 5)
  159. return uint64(tempDayTime.UnixNano() / 1e6)
  160. }
  161. // 获取最近周一5点更新时间(结束时间戳)
  162. func GetLatestWeek5HourTime(ms uint64) time.Time {
  163. loc := GetLoc()
  164. nowTime := GetCurrentTimeNow()
  165. if ms > 0 {
  166. nowTime = GetTimeByUint64(ms)
  167. }
  168. curWeekDay := nowTime.Weekday()
  169. if curWeekDay == 0 {
  170. curWeekDay = 7
  171. }
  172. delDay := 7 - curWeekDay + 1
  173. if curWeekDay == 1 {
  174. if nowTime.Hour() >= 5 {
  175. delDay = 7
  176. } else {
  177. delDay = 0
  178. }
  179. }
  180. nowTime = nowTime.AddDate(0, 0, int(delDay))
  181. dayTimeStr := nowTime.Format(DATE_FORMAT1)
  182. tempDayTime, _ := time.ParseInLocation(DATE_FORMAT1, dayTimeStr, loc)
  183. tempDayTime = tempDayTime.Add(time.Hour * 5)
  184. return tempDayTime
  185. }
  186. // 获取最近周日22点更新时间(结束时间戳)
  187. func GetLatestWeek10HourTime(ms uint64) time.Time {
  188. loc := GetLoc()
  189. nowTime := GetCurrentTimeNow()
  190. if ms > 0 {
  191. nowTime = GetTimeByUint64(ms)
  192. }
  193. curWeekDay := nowTime.Weekday()
  194. if curWeekDay == 0 {
  195. curWeekDay = 7
  196. }
  197. delDay := 7 - curWeekDay
  198. nowTime = nowTime.AddDate(0, 0, int(delDay))
  199. dayTimeStr := nowTime.Format(DATE_FORMAT1)
  200. tempDayTime, _ := time.ParseInLocation(DATE_FORMAT1, dayTimeStr, loc)
  201. tempDayTime = tempDayTime.Add(time.Hour * 22)
  202. return tempDayTime
  203. }
  204. func GetLatestMonth5Hour() uint64 {
  205. loc := GetLoc()
  206. nowTime := GetCurrentTimeNow()
  207. year, month, day := nowTime.Date()
  208. //如果是每个月的1号5点之前
  209. if day == 1 && nowTime.Hour() < 5 {
  210. return GetLatest5Hour()
  211. }
  212. //如果是一个月的1号5点之后
  213. thisMonth := time.Date(year, month, 1, 0, 0, 0, 0, time.Local)
  214. nextMonth := thisMonth.AddDate(0, 1, 0)
  215. dayTimeStr := nextMonth.Format(DATE_FORMAT1)
  216. tempDayTime, _ := time.ParseInLocation(DATE_FORMAT1, dayTimeStr, loc)
  217. tempDayTime = tempDayTime.Add(time.Hour * 5)
  218. return uint64(tempDayTime.UnixNano() / 1e6)
  219. }
  220. // 获取两个时间的持续天数
  221. func GetDurationDay(t1, t2 string) int64 {
  222. loc := GetLoc()
  223. t1DayStr := GetDayByTimeStr(t1)
  224. t2DayStr := GetDayByTimeStr(t2)
  225. sTime1, _ := time.ParseInLocation(DATE_FORMAT1, t1DayStr, loc)
  226. eTime1, _ := time.ParseInLocation(DATE_FORMAT1, t2DayStr, loc)
  227. return eTime1.Unix() - sTime1.Unix()
  228. }
  229. // t1, t2 (ms) t2 > t1
  230. func GetDurationDay1(t1, t2 uint64) int32 {
  231. loc := GetLoc()
  232. tmpT1 := GetTimeByUint64(t1)
  233. tmpT2 := GetTimeByUint64(t2)
  234. dayT1Str := tmpT1.Format(DATE_FORMAT1)
  235. dayT1, _ := time.ParseInLocation(DATE_FORMAT1, dayT1Str, loc)
  236. dayT2Str := tmpT2.Format(DATE_FORMAT1)
  237. dayT2, _ := time.ParseInLocation(DATE_FORMAT1, dayT2Str, loc)
  238. return int32(dayT2.Sub(dayT1).Hours() / 24)
  239. }
  240. // 以5点位分割线 t2 > t1
  241. func GetDurationDay2(t1, t2 uint64) int32 {
  242. loc := GetLoc()
  243. tmpT1 := GetTimeByUint64(t1)
  244. tmpT2 := GetTimeByUint64(t2)
  245. dayT1Str := tmpT1.Format(DATE_FORMAT1)
  246. dayT1, _ := time.ParseInLocation(DATE_FORMAT1, dayT1Str, loc)
  247. dayT2Str := tmpT2.Format(DATE_FORMAT1)
  248. dayT2, _ := time.ParseInLocation(DATE_FORMAT1, dayT2Str, loc)
  249. deltaDay := int32(dayT2.Sub(dayT1).Hours() / 24)
  250. if tmpT1.Hour() < 5 {
  251. deltaDay += 1
  252. }
  253. if tmpT2.Hour() >= 5 {
  254. deltaDay += 1
  255. }
  256. return deltaDay
  257. }
  258. // t1 < t2
  259. func IsInSameWeek(t1, t2 uint64) bool {
  260. if t2 < t1 {
  261. return false
  262. }
  263. tmpT1 := GetLatestWeek5Hour(t1)
  264. if t1 <= tmpT1 && t2 > tmpT1 {
  265. return true
  266. }
  267. return false
  268. }
  269. type baseTimer struct {
  270. ts uint64 //上一次时间戳
  271. duration uint64 //持续时间
  272. cancel bool //取消标记
  273. suspend bool //是否暂停
  274. resetTime uint64 //剩余时间 暂停后会用到
  275. }
  276. func (this *baseTimer) Cancel() {
  277. this.cancel = true
  278. this.ts = 0
  279. this.duration = 0
  280. this.suspend = false
  281. this.resetTime = 0
  282. }
  283. func (this *baseTimer) Canceled() bool {
  284. return this.cancel
  285. }
  286. func (this *baseTimer) Suspend() {
  287. this.suspend = true
  288. deltaT := this.duration - (GetCurrentTime() - this.ts)
  289. if deltaT >= this.duration {
  290. this.resetTime = 0
  291. } else {
  292. this.resetTime = this.duration - this.ts
  293. }
  294. }
  295. func (this *baseTimer) Resume() {
  296. this.suspend = false
  297. this.ts = GetCurrentTime()
  298. }
  299. func (this *baseTimer) IsStart() bool {
  300. return this.ts != 0
  301. }
  302. // 只运行一次的定时器
  303. type OnceTimer struct {
  304. baseTimer
  305. }
  306. func NewOnceTimer(ms uint64, duration time.Duration) ServerTimer {
  307. t := &OnceTimer{
  308. baseTimer: baseTimer{
  309. ts: ms,
  310. duration: uint64(duration),
  311. cancel: false,
  312. suspend: false,
  313. resetTime: 0,
  314. },
  315. }
  316. return t
  317. }
  318. func (this *OnceTimer) IsExpired(ms uint64) bool {
  319. if this.cancel || this.suspend {
  320. return false
  321. }
  322. if this.resetTime > 0 {
  323. if (this.ts + this.resetTime) < ms {
  324. this.resetTime = 0
  325. return true
  326. } else {
  327. return false
  328. }
  329. }
  330. return (this.ts + this.duration) < ms
  331. }
  332. func (this *OnceTimer) Reset(ms uint64, duration time.Duration, fireNow bool) {
  333. this.ts = ms
  334. this.duration = uint64(duration)
  335. this.cancel = false
  336. }
  337. // 运行无限次定时器
  338. type DurationTimer struct {
  339. baseTimer
  340. fireNow bool //建立后可以立即被触发无论是否过期
  341. expiredTimes int32 //过期次数
  342. }
  343. func NewDurationTimer(ms uint64, duration time.Duration) ServerTimer {
  344. t := &DurationTimer{
  345. fireNow: false,
  346. expiredTimes: 0,
  347. baseTimer: baseTimer{
  348. ts: ms,
  349. duration: uint64(duration),
  350. cancel: false,
  351. suspend: false,
  352. resetTime: 0,
  353. },
  354. }
  355. return t
  356. }
  357. func (this *DurationTimer) IsExpired(ms uint64) bool {
  358. if this.cancel || this.suspend {
  359. return false
  360. }
  361. if this.resetTime > 0 {
  362. if (this.ts + this.resetTime) < ms {
  363. this.resetTime = 0
  364. this.Reset(ms, time.Duration(this.duration), true)
  365. return true
  366. } else {
  367. return false
  368. }
  369. }
  370. ret := (this.ts + this.duration) < ms
  371. if ret {
  372. this.expiredTimes++
  373. this.ts = ms
  374. }
  375. if this.fireNow {
  376. this.fireNow = false
  377. return true
  378. }
  379. return ret
  380. }
  381. func (this *DurationTimer) Reset(ms uint64, duration time.Duration, fireNow bool) {
  382. this.ts = ms
  383. this.duration = uint64(duration)
  384. this.cancel = false
  385. this.fireNow = fireNow
  386. }