package utils import ( "errors" "log" "math" "strconv" "strings" "time" ) type ITimer struct { *time.Timer name string exited bool isRunning bool d time.Duration fn func() } func itimerDefaultFunc() {} func NewTimer(d time.Duration) *ITimer { tm := &ITimer{ Timer: time.NewTimer(d), exited: false, isRunning: true, d: d, fn: itimerDefaultFunc, } tm.Pause() return tm } func (tm *ITimer) SetName(nm string) { tm.name = nm } func (tm *ITimer) Name() string { return tm.name } func (tm *ITimer) Exit() bool { tm.exited = tm.Timer.Reset(0) return tm.exited } func (tm *ITimer) IsExit() bool { return tm.exited } func (tm *ITimer) reset() bool { if tm.exited { return false } tm.isRunning = true return tm.Timer.Reset(tm.d) } func (tm *ITimer) Pause() bool { tm.isRunning = false return tm.Timer.Reset(time.Duration(math.MaxInt64)) } func (tm *ITimer) Continue() bool { tm.isRunning = true return tm.reset() } func (tm *ITimer) IsRunning() bool { if tm.exited { return false } return tm.isRunning } func (tm *ITimer) SetFunc(fn func()) { tm.fn = fn } func (tm *ITimer) NowExecFunc() { if tm.fn != nil { go tm.fn() } tm.reset() } func (tm *ITimer) Run() { for { select { case <-tm.C: if tm.IsExit() { tm.isRunning = false return } tm.reset() if tm.fn != nil { go tm.fn() } } } } //format time like java, such as: yyyy-MM-dd HH:mm:ss func TimeFormat(t time.Time, format string) string { //year if strings.ContainsAny(format, "y") { year := strconv.Itoa(t.Year()) if strings.Count(format, "yy") == 1 && strings.Count(format, "y") == 2 { format = strings.Replace(format, "yy", year[2:], 1) } else if strings.Count(format, "yyyy") == 1 && strings.Count(format, "y") == 4 { format = strings.Replace(format, "yyyy", year, 1) } else { log.Fatalln("format year error! please 'yyyy' or 'yy'") } } //month if strings.ContainsAny(format, "M") { var month string if int(t.Month()) < 10 { month = "0" + strconv.Itoa(int(t.Month())) } else { month = strconv.Itoa(int(t.Month())) } if strings.Count(format, "MM") == 1 && strings.Count(format, "M") == 2 { format = strings.Replace(format, "MM", month, 1) } else { log.Fatalln("format month error! please 'MM'") } } //day if strings.ContainsAny(format, "d") { var day string if t.Day() < 10 { day = "0" + strconv.Itoa(t.Day()) } else { day = strconv.Itoa(t.Day()) } if strings.Count(format, "dd") == 1 && strings.Count(format, "d") == 2 { format = strings.Replace(format, "dd", day, 1) } else { log.Fatalln("format day error! please 'dd'") } } //hour if strings.ContainsAny(format, "H") { var hour string if t.Hour() < 10 { hour = "0" + strconv.Itoa(t.Hour()) } else { hour = strconv.Itoa(t.Hour()) } if strings.Count(format, "HH") == 1 && strings.Count(format, "H") == 2 { format = strings.Replace(format, "HH", hour, 1) } else { log.Fatalln("format hour error! please 'HH'") } } //minute if strings.ContainsAny(format, "m") { var minute string if t.Minute() < 10 { minute = "0" + strconv.Itoa(t.Minute()) } else { minute = strconv.Itoa(t.Minute()) } if strings.Count(format, "mm") == 1 && strings.Count(format, "m") == 2 { format = strings.Replace(format, "mm", minute, 1) } else { log.Fatalln("format minute error! please 'mm'") } } //second if strings.ContainsAny(format, "s") { var second string if t.Second() < 10 { second = "0" + strconv.Itoa(t.Second()) } else { second = strconv.Itoa(t.Second()) } if strings.Count(format, "ss") == 1 && strings.Count(format, "s") == 2 { format = strings.Replace(format, "ss", second, 1) } else { log.Fatalln("format second error! please 'ss'") } } return format } //2007-11-23 10:02:14/20071123100214 func TimeParse(str string) (time.Time, error) { ll := len(str) if ll == 19 { loc, _ := time.LoadLocation("Local") return time.ParseInLocation("2006-01-02 15:04:05", str, loc) } else if ll == 14 { loc, _ := time.LoadLocation("Local") return time.ParseInLocation("20060102150405", str, loc) } return time.Time{}, errors.New("str len is error") } //17:02:03/170203 func TimeParseHHmmss(str string) (time.Time, error) { ll := len(str) if ll != 8 && ll != 6 { return time.Time{}, errors.New("input str is error") } if ll == 8 { return TimeParse(TimeFormat(time.Now(), "yyyy-MM-dd "+str)) } return TimeParse(TimeFormat(time.Now(), "yyyyMMdd"+str)) } //17:02/1702 func TimeParseHHmm(str string) (time.Time, error) { ll := len(str) if ll != 5 && ll != 4 { return time.Time{}, errors.New("input str is error") } if ll == 5 { return TimeParse(TimeFormat(time.Now(), "yyyy-MM-dd "+str+":00")) } return TimeParse(TimeFormat(time.Now(), "yyyyMMdd"+str+"00")) } //2007-05-69/20070569 func TimeParseyyyyMMdd(str string) (time.Time, error) { ll := len(str) if ll != 10 && ll != 8 { return time.Time{}, errors.New("input str is error") } if ll == 10 { return TimeParse(TimeFormat(time.Now(), str+" 00:00:00")) } return TimeParse(TimeFormat(time.Now(), str+"000000")) } //计算时间差返回秒级 样例: T1 = 16:00 t2 = 08:00 func Timelen(t1 string, t2 string) (int, error) { var time1 int64 var time2 int64 len1 := len(t1) if len1 != 4 && len1 != 5 { return 0, errors.New("input str is error") } len2 := len(t2) if len2 != 4 && len2 != 5 { return 0, errors.New("input str is error") } tem1, _ := TimeParseHHmm(t1) time1 = tem1.Unix() tem2, _ := TimeParseHHmm(t2) time2 = tem2.Unix() timelen := time1 - time2 return int(timelen), nil } //获取某一天的0点时间 func GetZeroTime(d time.Time) time.Time { now := time.Date(d.Year(), d.Month(), d.Day(), 0, 0, 0, 0, d.Location()) return now } //返回格式:例如2016-05-01 00:00:00的时间戳到2016-06-01 00:00:00的时间戳 func TimeReturnMonth(now time.Time) (firstMonth string, lastMonth string) { currentYear, currentMonth, _ := now.Date() currentLocation := now.Location() firstOfMonth := time.Date(currentYear, currentMonth, 1, 0, 0, 0, 0, currentLocation) lastOfMonth := firstOfMonth.AddDate(0, 1, 0).Add(time.Second * -1) return TimeFormat(firstOfMonth,"yyyyMMdd"), TimeFormat(lastOfMonth,"yyyyMMdd") }