package utils import ( "errors" "fmt" "log" "math" "strconv" "strings" "time" ) var TimezoneLocation *time.Location 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") } // GetCrossDays 获取两个时间点之间的天数 func GetCrossDays(t1, t2 time.Time) (days int) { var ( y1, d1, y2, d2 int m1, m2 time.Month date1, date2 time.Time ) days = 0 if t1.Unix() >= t2.Unix() { return } y1, m1, d1 = t1.Date() y2, m2, d2 = t2.Date() date1 = time.Date(y1, m1, d1, 0, 0, 0, 0, time.UTC) date2 = time.Date(y2, m2, d2, 0, 0, 0, 0, time.UTC) days = int(date2.Sub(date1).Hours() / 24) return } // 获取时间点的日期,以年月日字符类型数据返回 func GetYMDString(t time.Time) (ymd string) { var ( y1, d1 int m1 time.Month ) y1, m1, d1 = t.Date() ymd = fmt.Sprintf("%04d", y1) + fmt.Sprintf("%02d", int(m1)) + fmt.Sprintf("%02d", d1) return } func ParseWeekIndex(date time.Time) int { dateStr := date.Format("2006-01-02") dateStr = dateStr[:8] + "01" firstDay, _ := time.ParseInLocation("2006-01-02", dateStr, TimezoneLocation) firstWeekDay := firstDay.Weekday() weekDay := date.Weekday() for i := 1; i < 6; i++ { date = date.AddDate(0, 0, -7) if date.Before(firstDay) { if weekDay >= firstWeekDay { return i } return i + 1 } } return 0 } // 获取线段上两个时间点之间的Duration func GetDuration(startTime, endTime time.Time, EffFactor float64) (duration time.Duration) { var seconds float64 if endTime.Unix() <= startTime.Unix() { duration = 0 return } if EffFactor <= 0 { EffFactor = 1 } seconds = endTime.Sub(startTime).Seconds() * EffFactor duration = time.Duration(seconds) * time.Second return } // GenerateTimeFormatForAcura 生成讴歌工单流水号中日期的格式 func GenerateTimeFormatForAcura(t time.Time) (dateStr string, err error) { year, month, day := t.Date() YearStr, exist := YEAR_MAP[year] if !exist { err = errors.New("年份映射值不存在") return } monthStr, exist := MONTH_MAP[int(month)] if !exist { err = errors.New("月份映射值不存在") return } dayStr, exist := DAY_MAP[day] if !exist { err = errors.New("天映射值不存在") return } return YearStr + monthStr + dayStr, nil } //获取两个时间,中间的所有年月日 + 时 集合 func GetHoursData(startTime, endTime time.Time) (data []string, err error) { if startTime.Unix() > endTime.Unix() { return nil, errors.New("开始时间大于结束时间!") } for { if startTime.Unix() > endTime.Unix() { return data, nil } year, month, day := startTime.Date() hour := startTime.Hour() nowTime := time.Date(year, month, day, hour, 0, 0, 0, startTime.Location()) keyTime := TimeFormat(nowTime, "yyyy-MM-dd HH:mm") data = append(data, keyTime) startTime = nowTime.Add(1 * time.Hour) } } // CalcDurationByUom 根据传入得数量和单位返回时间 func CalcDurationByUom(qty float64, uom string) time.Duration { seconds := GetTimeUomSeconds(uom) return time.Duration(float64(qty) * seconds) } // GetTimeUomSeconds 基于时间单位获取秒数 func GetTimeUomSeconds(uomId string) (seconds float64) { seconds = 0 switch strings.ToUpper(uomId) { case TIME_UOM_WEEK: seconds = 7 * 24 * 3600 case TIME_UOM_DAY: seconds = 24 * 3600 case TIME_UOM_HOUR: seconds = 3600 case TIME_UOM_MINUTE: seconds = 60 case TIME_UOM_SECOND: seconds = 1 } return } const ( // 时间类型 TIME_UOM_WEEK = "WEEK" TIME_UOM_DAY = "DAY" TIME_UOM_HOUR = "HOUR" TIME_UOM_MINUTE = "MINUTE" TIME_UOM_SECOND = "SECOND" )