| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388 |
- package util
- import (
- "time"
- )
- //定时器接口
- type ServerTimer interface {
- //测试是否过期
- IsExpired(ms uint64) bool
- //重置
- Reset(ms uint64, duration time.Duration, fireNow bool)
- Cancel()
- Canceled() bool
- Suspend()
- Resume()
- IsStart() bool
- }
- const DATE_FORMAT = "2006-01-02 15:04:05"
- const DATE_FORMAT_T = "2006-01-02T15:04:05"
- const DATE_FORMAT1 = "2006-01-02"
- const DATE_FORMAT2 = "15:04:05"
- const DATE_FORMAT3 = "15:04"
- var gameLoc *time.Location = nil
- func GetLoc() *time.Location {
- if gameLoc == nil {
- loc, err := time.LoadLocation("Asia/Shanghai")
- if err != nil {
- gameLoc = time.Local
- } else {
- gameLoc = loc
- }
- }
- return gameLoc
- }
- //return ms
- func GetCurrentTime() uint64 {
- t1 := GetCurrentTimeNow()
- return uint64(t1.UnixNano() / 1e6)
- }
- func GetCurrentTimeNow() time.Time {
- loc := GetLoc()
- t1 := time.Now()
- return t1.In(loc)
- }
- func GetTimeMilliseconds() uint64 {
- return GetCurrentTime()
- }
- func GetTimeSeconds() int64 {
- return GetCurrentTimeNow().Unix()
- }
- func GetTimeByStr(timeStr string) time.Time {
- tempTime, _ := time.ParseInLocation(DATE_FORMAT, timeStr, GetLoc())
- return tempTime
- }
- func GetTimeByUint64(uTime uint64) time.Time {
- timeS := int64(uTime / 1000)
- timeMS := int64(uTime % 1000)
- return time.Unix(timeS, timeMS).In(GetLoc())
- }
- func GetTimeByUint32(uTime uint32) time.Time {
- return time.Unix(int64(uTime), 0).In(GetLoc())
- }
- func GetHourByTime(uTime uint64) time.Time {
- loc := GetLoc()
- if uTime <= 0 {
- tempTimeStr := GetCurrentTimeNow().Format(DATE_FORMAT2)
- tempTime, _ := time.ParseInLocation(DATE_FORMAT2, tempTimeStr, loc)
- return tempTime
- } else {
- tempTimeStr := GetTimeByUint64(uTime).Format(DATE_FORMAT2)
- tempTime, _ := time.ParseInLocation(DATE_FORMAT2, tempTimeStr, loc)
- return tempTime
- }
- }
- func GetHourByTimeStr(timeStr string) string {
- loc := GetLoc()
- tempTime, _ := time.ParseInLocation(DATE_FORMAT, timeStr, loc)
- tempTime1 := tempTime.Format(DATE_FORMAT2)
- return tempTime1
- }
- func GetHourByTimeStr1(timeStr string) time.Time {
- loc := GetLoc()
- hTime, _ := time.ParseInLocation(DATE_FORMAT2, timeStr, loc)
- return hTime
- }
- func GetDayByTimeStr(timeStr string) string {
- loc := GetLoc()
- sTime, _ := time.ParseInLocation(DATE_FORMAT, timeStr, loc)
- return sTime.Format(DATE_FORMAT1)
- }
- func GetDayByTimeStr1(timeStr string) time.Time {
- loc := GetLoc()
- dTime, _ := time.ParseInLocation(DATE_FORMAT1, timeStr, loc)
- return dTime
- }
- func GetDayByTimeStr2(timeMs uint64) time.Time {
- loc := GetLoc()
- tempTimeStr := GetTimeByUint64(timeMs).Format(DATE_FORMAT1)
- tempTime, _ := time.ParseInLocation(DATE_FORMAT1, tempTimeStr, loc)
- return tempTime
- }
- func GetDayAndHourByTimeStr(timeStr string) (string, string) {
- loc := GetLoc()
- tempTime, _ := time.ParseInLocation(DATE_FORMAT, timeStr, loc)
- hourStr := tempTime.Format(DATE_FORMAT2)
- dayStr := tempTime.Format(DATE_FORMAT1)
- return dayStr, hourStr
- }
- func GetDayAndHourByTime(timeStr string) (time.Time, time.Time) {
- loc := GetLoc()
- tempTime, _ := time.ParseInLocation(DATE_FORMAT, timeStr, loc)
- dayStr := tempTime.Format(DATE_FORMAT1)
- d, _ := time.ParseInLocation(DATE_FORMAT1, dayStr, loc)
- hourStr := tempTime.Format(DATE_FORMAT2)
- h, _ := time.ParseInLocation(DATE_FORMAT2, hourStr, loc)
- return d, h
- }
- //获取最近一天5点更新时间(结束时间戳)
- func GetLatest5Hour() uint64 {
- loc := GetLoc()
- nowTime := GetCurrentTimeNow()
- if nowTime.Hour() < 5 {
- dayTimeStr := nowTime.Format(DATE_FORMAT1)
- tempDayTime, _ := time.ParseInLocation(DATE_FORMAT1, dayTimeStr, loc)
- tempDayTime = tempDayTime.Add(time.Hour * 5)
- return uint64(tempDayTime.UnixNano() / 1e6)
- } else {
- dayTimeStr := nowTime.Format(DATE_FORMAT1)
- tempDayTime, _ := time.ParseInLocation(DATE_FORMAT1, dayTimeStr, loc)
- tempDayTime = tempDayTime.Add(time.Hour * 24)
- dayTimeStr = tempDayTime.Format(DATE_FORMAT1)
- tempDayTime, _ = time.ParseInLocation(DATE_FORMAT1, dayTimeStr, loc)
- tempDayTime = tempDayTime.Add(time.Hour * 5)
- return uint64(tempDayTime.UnixNano() / 1e6)
- }
- }
- //获取最近周一5点更新时间(结束时间戳)
- func GetLatestWeek5Hour(ms uint64) uint64 {
- loc := GetLoc()
- nowTime := GetCurrentTimeNow()
- if ms > 0 {
- nowTime = GetTimeByUint64(ms)
- }
- curWeekDay := nowTime.Weekday()
- if curWeekDay == 0 {
- curWeekDay = 7
- }
- delDay := 7 - curWeekDay + 1
- if curWeekDay == 1 {
- if nowTime.Hour() >= 5 {
- delDay = 7
- } else {
- delDay = 0
- }
- }
- nowTime = nowTime.AddDate(0, 0, int(delDay))
- dayTimeStr := nowTime.Format(DATE_FORMAT1)
- tempDayTime, _ := time.ParseInLocation(DATE_FORMAT1, dayTimeStr, loc)
- tempDayTime = tempDayTime.Add(time.Hour * 5)
- return uint64(tempDayTime.UnixNano() / 1e6)
- }
- func GetLatestMonth5Hour() uint64 {
- loc := GetLoc()
- nowTime := GetCurrentTimeNow()
- year, month, day := nowTime.Date()
- //如果是每个月的1号5点之前
- if day == 1 && nowTime.Hour() < 5 {
- return GetLatest5Hour()
- }
- //如果是一个月的1号5点之后
- thisMonth := time.Date(year, month, 1, 0, 0, 0, 0, time.Local)
- nextMonth := thisMonth.AddDate(0, 1, 0)
- dayTimeStr := nextMonth.Format(DATE_FORMAT1)
- tempDayTime, _ := time.ParseInLocation(DATE_FORMAT1, dayTimeStr, loc)
- tempDayTime = tempDayTime.Add(time.Hour * 5)
- return uint64(tempDayTime.UnixNano() / 1e6)
- }
- //获取两个时间的持续天数
- func GetDurationDay(t1, t2 string) int64 {
- loc := GetLoc()
- t1DayStr := GetDayByTimeStr(t1)
- t2DayStr := GetDayByTimeStr(t2)
- sTime1, _ := time.ParseInLocation(DATE_FORMAT1, t1DayStr, loc)
- eTime1, _ := time.ParseInLocation(DATE_FORMAT1, t2DayStr, loc)
- return eTime1.Unix() - sTime1.Unix()
- }
- //t1, t2 (ms) t2 > t1
- func GetDurationDay1(t1, t2 uint64) int32 {
- loc := GetLoc()
- tmpT1 := GetTimeByUint64(t1)
- tmpT2 := GetTimeByUint64(t2)
- dayT1Str := tmpT1.Format(DATE_FORMAT1)
- dayT1, _ := time.ParseInLocation(DATE_FORMAT1, dayT1Str, loc)
- dayT2Str := tmpT2.Format(DATE_FORMAT1)
- dayT2, _ := time.ParseInLocation(DATE_FORMAT1, dayT2Str, loc)
- return int32(dayT2.Sub(dayT1).Hours() / 24)
- }
- //以5点位分割线 t2 > t1
- func GetDurationDay2(t1, t2 uint64) int32 {
- loc := GetLoc()
- tmpT1 := GetTimeByUint64(t1)
- tmpT2 := GetTimeByUint64(t2)
- dayT1Str := tmpT1.Format(DATE_FORMAT1)
- dayT1, _ := time.ParseInLocation(DATE_FORMAT1, dayT1Str, loc)
- dayT2Str := tmpT2.Format(DATE_FORMAT1)
- dayT2, _ := time.ParseInLocation(DATE_FORMAT1, dayT2Str, loc)
- deltaDay := int32(dayT2.Sub(dayT1).Hours() / 24)
- if tmpT1.Hour() < 5 {
- deltaDay += 1
- }
- if tmpT2.Hour() >= 5 {
- deltaDay += 1
- }
- return deltaDay
- }
- //t1 < t2
- func IsInSameWeek(t1, t2 uint64) bool {
- if t2 < t1 {
- return false
- }
- tmpT1 := GetLatestWeek5Hour(t1)
- if t1 <= tmpT1 && t2 > tmpT1 {
- return true
- }
- return false
- }
- type baseTimer struct {
- ts uint64 //上一次时间戳
- duration uint64 //持续时间
- cancel bool //取消标记
- suspend bool //是否暂停
- resetTime uint64 //剩余时间 暂停后会用到
- }
- func (this *baseTimer) Cancel() {
- this.cancel = true
- this.ts = 0
- this.duration = 0
- this.suspend = false
- this.resetTime = 0
- }
- func (this *baseTimer) Canceled() bool {
- return this.cancel
- }
- func (this *baseTimer) Suspend() {
- this.suspend = true
- deltaT := this.duration - (GetCurrentTime() - this.ts)
- if deltaT >= this.duration {
- this.resetTime = 0
- } else {
- this.resetTime = this.duration - this.ts
- }
- }
- func (this *baseTimer) Resume() {
- this.suspend = false
- this.ts = GetCurrentTime()
- }
- func (this *baseTimer) IsStart() bool {
- return this.ts != 0
- }
- //只运行一次的定时器
- type OnceTimer struct {
- baseTimer
- }
- func NewOnceTimer(ms uint64, duration time.Duration) ServerTimer {
- t := &OnceTimer{
- baseTimer: baseTimer{
- ts: ms,
- duration: uint64(duration),
- cancel: false,
- suspend: false,
- resetTime: 0,
- },
- }
- return t
- }
- func (this *OnceTimer) IsExpired(ms uint64) bool {
- if this.cancel || this.suspend {
- return false
- }
- if this.resetTime > 0 {
- if (this.ts + this.resetTime) < ms {
- this.resetTime = 0
- return true
- } else {
- return false
- }
- }
- return (this.ts + this.duration) < ms
- }
- func (this *OnceTimer) Reset(ms uint64, duration time.Duration, fireNow bool) {
- this.ts = ms
- this.duration = uint64(duration)
- this.cancel = false
- }
- //运行无限次定时器
- type DurationTimer struct {
- baseTimer
- fireNow bool //建立后可以立即被触发无论是否过期
- expiredTimes int32 //过期次数
- }
- func NewDurationTimer(ms uint64, duration time.Duration) ServerTimer {
- t := &DurationTimer{
- fireNow: false,
- expiredTimes: 0,
- baseTimer: baseTimer{
- ts: ms,
- duration: uint64(duration),
- cancel: false,
- suspend: false,
- resetTime: 0,
- },
- }
- return t
- }
- func (this *DurationTimer) IsExpired(ms uint64) bool {
- if this.cancel || this.suspend {
- return false
- }
- if this.resetTime > 0 {
- if (this.ts + this.resetTime) < ms {
- this.resetTime = 0
- this.Reset(ms, time.Duration(this.duration), true)
- return true
- } else {
- return false
- }
- }
- ret := (this.ts + this.duration) < ms
- if ret {
- this.expiredTimes++
- this.ts = ms
- }
- if this.fireNow {
- this.fireNow = false
- return true
- }
- return ret
- }
- func (this *DurationTimer) Reset(ms uint64, duration time.Duration, fireNow bool) {
- this.ts = ms
- this.duration = uint64(duration)
- this.cancel = false
- this.fireNow = fireNow
- }
|