timer.go 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  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. func GetLatestMonth5Hour() uint64 {
  162. loc := GetLoc()
  163. nowTime := GetCurrentTimeNow()
  164. year, month, day := nowTime.Date()
  165. //如果是每个月的1号5点之前
  166. if day == 1 && nowTime.Hour() < 5 {
  167. return GetLatest5Hour()
  168. }
  169. //如果是一个月的1号5点之后
  170. thisMonth := time.Date(year, month, 1, 0, 0, 0, 0, time.Local)
  171. nextMonth := thisMonth.AddDate(0, 1, 0)
  172. dayTimeStr := nextMonth.Format(DATE_FORMAT1)
  173. tempDayTime, _ := time.ParseInLocation(DATE_FORMAT1, dayTimeStr, loc)
  174. tempDayTime = tempDayTime.Add(time.Hour * 5)
  175. return uint64(tempDayTime.UnixNano() / 1e6)
  176. }
  177. //获取两个时间的持续天数
  178. func GetDurationDay(t1, t2 string) int64 {
  179. loc := GetLoc()
  180. t1DayStr := GetDayByTimeStr(t1)
  181. t2DayStr := GetDayByTimeStr(t2)
  182. sTime1, _ := time.ParseInLocation(DATE_FORMAT1, t1DayStr, loc)
  183. eTime1, _ := time.ParseInLocation(DATE_FORMAT1, t2DayStr, loc)
  184. return eTime1.Unix() - sTime1.Unix()
  185. }
  186. //t1, t2 (ms) t2 > t1
  187. func GetDurationDay1(t1, t2 uint64) int32 {
  188. loc := GetLoc()
  189. tmpT1 := GetTimeByUint64(t1)
  190. tmpT2 := GetTimeByUint64(t2)
  191. dayT1Str := tmpT1.Format(DATE_FORMAT1)
  192. dayT1, _ := time.ParseInLocation(DATE_FORMAT1, dayT1Str, loc)
  193. dayT2Str := tmpT2.Format(DATE_FORMAT1)
  194. dayT2, _ := time.ParseInLocation(DATE_FORMAT1, dayT2Str, loc)
  195. return int32(dayT2.Sub(dayT1).Hours() / 24)
  196. }
  197. //以5点位分割线 t2 > t1
  198. func GetDurationDay2(t1, t2 uint64) int32 {
  199. loc := GetLoc()
  200. tmpT1 := GetTimeByUint64(t1)
  201. tmpT2 := GetTimeByUint64(t2)
  202. dayT1Str := tmpT1.Format(DATE_FORMAT1)
  203. dayT1, _ := time.ParseInLocation(DATE_FORMAT1, dayT1Str, loc)
  204. dayT2Str := tmpT2.Format(DATE_FORMAT1)
  205. dayT2, _ := time.ParseInLocation(DATE_FORMAT1, dayT2Str, loc)
  206. deltaDay := int32(dayT2.Sub(dayT1).Hours() / 24)
  207. if tmpT1.Hour() < 5 {
  208. deltaDay += 1
  209. }
  210. if tmpT2.Hour() >= 5 {
  211. deltaDay += 1
  212. }
  213. return deltaDay
  214. }
  215. //t1 < t2
  216. func IsInSameWeek(t1, t2 uint64) bool {
  217. if t2 < t1 {
  218. return false
  219. }
  220. tmpT1 := GetLatestWeek5Hour(t1)
  221. if t1 <= tmpT1 && t2 > tmpT1 {
  222. return true
  223. }
  224. return false
  225. }
  226. type baseTimer struct {
  227. ts uint64 //上一次时间戳
  228. duration uint64 //持续时间
  229. cancel bool //取消标记
  230. suspend bool //是否暂停
  231. resetTime uint64 //剩余时间 暂停后会用到
  232. }
  233. func (this *baseTimer) Cancel() {
  234. this.cancel = true
  235. this.ts = 0
  236. this.duration = 0
  237. this.suspend = false
  238. this.resetTime = 0
  239. }
  240. func (this *baseTimer) Canceled() bool {
  241. return this.cancel
  242. }
  243. func (this *baseTimer) Suspend() {
  244. this.suspend = true
  245. deltaT := this.duration - (GetCurrentTime() - this.ts)
  246. if deltaT >= this.duration {
  247. this.resetTime = 0
  248. } else {
  249. this.resetTime = this.duration - this.ts
  250. }
  251. }
  252. func (this *baseTimer) Resume() {
  253. this.suspend = false
  254. this.ts = GetCurrentTime()
  255. }
  256. func (this *baseTimer) IsStart() bool {
  257. return this.ts != 0
  258. }
  259. //只运行一次的定时器
  260. type OnceTimer struct {
  261. baseTimer
  262. }
  263. func NewOnceTimer(ms uint64, duration time.Duration) ServerTimer {
  264. t := &OnceTimer{
  265. baseTimer: baseTimer{
  266. ts: ms,
  267. duration: uint64(duration),
  268. cancel: false,
  269. suspend: false,
  270. resetTime: 0,
  271. },
  272. }
  273. return t
  274. }
  275. func (this *OnceTimer) IsExpired(ms uint64) bool {
  276. if this.cancel || this.suspend {
  277. return false
  278. }
  279. if this.resetTime > 0 {
  280. if (this.ts + this.resetTime) < ms {
  281. this.resetTime = 0
  282. return true
  283. } else {
  284. return false
  285. }
  286. }
  287. return (this.ts + this.duration) < ms
  288. }
  289. func (this *OnceTimer) Reset(ms uint64, duration time.Duration, fireNow bool) {
  290. this.ts = ms
  291. this.duration = uint64(duration)
  292. this.cancel = false
  293. }
  294. //运行无限次定时器
  295. type DurationTimer struct {
  296. baseTimer
  297. fireNow bool //建立后可以立即被触发无论是否过期
  298. expiredTimes int32 //过期次数
  299. }
  300. func NewDurationTimer(ms uint64, duration time.Duration) ServerTimer {
  301. t := &DurationTimer{
  302. fireNow: false,
  303. expiredTimes: 0,
  304. baseTimer: baseTimer{
  305. ts: ms,
  306. duration: uint64(duration),
  307. cancel: false,
  308. suspend: false,
  309. resetTime: 0,
  310. },
  311. }
  312. return t
  313. }
  314. func (this *DurationTimer) IsExpired(ms uint64) bool {
  315. if this.cancel || this.suspend {
  316. return false
  317. }
  318. if this.resetTime > 0 {
  319. if (this.ts + this.resetTime) < ms {
  320. this.resetTime = 0
  321. this.Reset(ms, time.Duration(this.duration), true)
  322. return true
  323. } else {
  324. return false
  325. }
  326. }
  327. ret := (this.ts + this.duration) < ms
  328. if ret {
  329. this.expiredTimes++
  330. this.ts = ms
  331. }
  332. if this.fireNow {
  333. this.fireNow = false
  334. return true
  335. }
  336. return ret
  337. }
  338. func (this *DurationTimer) Reset(ms uint64, duration time.Duration, fireNow bool) {
  339. this.ts = ms
  340. this.duration = uint64(duration)
  341. this.cancel = false
  342. this.fireNow = fireNow
  343. }