|
|
- 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")
- }
-
- // 获取两个时间点之间的天数
- 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
- }
-
- func ZellerFunction2Week(year, month, day uint16) int {
-
- var y, m, c uint16
-
- if month >= 3 {
-
- m = month
-
- y = year % 100
-
- c = year / 100
-
- } else {
-
- m = month + 12
-
- y = (year - 1) % 100
-
- c = (year - 1) / 100
-
- }
-
- week := y + (y / 4) + (c / 4) - 2*c + ((26 * (m + 1)) / 10) + day - 1
-
- if week < 0 {
-
- week = 7 - (-week)%7
-
- } else {
-
- week = week % 7
-
- }
-
- which_week := int(week)
-
- return which_week
-
- }
-
- //判断时间是当年的第几周
- func WeekByDate(t time.Time) (int, int, time.Month) {
- var yearFirstDay time.Time
-
- var yearDay int
- //计算当前时间是周几
- year, month, day := t.Date()
-
- firstWeek := ZellerFunction2Week(uint16(year), uint16(month), uint16(day))
- dayLen := 7 - firstWeek
- //计算周日的时间,防止跨年
- startDate := t.AddDate(0, 0, dayLen)
- nextyear, nextmonth, _ := startDate.Date()
- //判断是否跨年
- if nextyear > year {
- year = nextyear
- month = nextmonth
- yearDay = startDate.YearDay()
- yearFirstDay = startDate.AddDate(0, 0, -yearDay+1)
- } else {
- yearDay = t.YearDay()
- yearFirstDay = t.AddDate(0, 0, -yearDay+1)
- }
-
- firstDayInWeek := int(yearFirstDay.Weekday())
-
- //今年第一周有几天
- firstWeekDays := 1
- if firstDayInWeek != 0 {
- firstWeekDays = 7 - firstDayInWeek + 1
- }
- var week int
- if yearDay <= firstWeekDays {
- week = 1
- } else {
- week = (yearDay-firstWeekDays)/7 + 2
- }
- return week, year, month
- }
-
- //判断时间是当年的第几周
- func WeekByDateStr(t time.Time) string {
- yearDay := t.YearDay()
- yearFirstDay := t.AddDate(0, 0, -yearDay+1)
- firstDayInWeek := int(yearFirstDay.Weekday())
-
- //今年第一周有几天
- firstWeekDays := 1
- if firstDayInWeek != 0 {
- firstWeekDays = 7 - firstDayInWeek + 1
- }
- var week int
- if yearDay <= firstWeekDays {
- week = 1
- } else {
- week = (yearDay-firstWeekDays)/7 + 2
- }
- return fmt.Sprintf("%d.%d", t.Year(), week)
- }
-
- type WeekDate struct {
- WeekTh string
- StartTime time.Time
- EndTime time.Time
- }
-
- // 将开始时间和结束时间分割为周为单位
- func GroupByWeekDate(startTime, endTime time.Time) []WeekDate {
- weekDate := make([]WeekDate, 0)
- diffDuration := endTime.Sub(startTime)
- days := int(math.Ceil(float64(diffDuration/(time.Hour*24)))) + 1
-
- currentWeekDate := WeekDate{}
- currentWeekDate.WeekTh = WeekByDateStr(endTime)
- currentWeekDate.EndTime = endTime
- currentWeekDay := int(endTime.Weekday())
- if currentWeekDay == 0 {
- currentWeekDay = 7
- }
- currentWeekDate.StartTime = endTime.AddDate(0, 0, -currentWeekDay+1)
- nextWeekEndTime := currentWeekDate.StartTime
- weekDate = append(weekDate, currentWeekDate)
-
- for i := 0; i < (days-currentWeekDay)/7; i++ {
- weekData := WeekDate{}
- weekData.EndTime = nextWeekEndTime
- weekData.StartTime = nextWeekEndTime.AddDate(0, 0, -7)
- weekData.WeekTh = WeekByDateStr(weekData.StartTime)
- nextWeekEndTime = weekData.StartTime
- weekDate = append(weekDate, weekData)
- }
-
- if lastDays := (days - currentWeekDay) % 7; lastDays > 0 {
- lastData := WeekDate{}
- lastData.EndTime = nextWeekEndTime
- lastData.StartTime = nextWeekEndTime.AddDate(0, 0, -lastDays)
- lastData.WeekTh = WeekByDateStr(lastData.StartTime)
- weekDate = append(weekDate, lastData)
- }
-
- return weekDate
- }
-
- //周一0点
- func WeekDayMondayZeroTs(now time.Time) time.Time {
- offset := int(time.Monday - now.Weekday())
- if offset > 0 {
- offset = -6
- }
-
- weekStart := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.Local).AddDate(0, 0, offset)
- return weekStart
- }
-
- func WeekDaySaturdayZeroTs(now time.Time) time.Time {
- offset := int(time.Monday - now.Weekday())
- if offset > 0 {
- offset = -6
- }
- offset += 5
-
- weekStart := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.Local).AddDate(0, 0, offset)
- return weekStart
- }
-
- func WeekDaySundayZeroTs(now time.Time) time.Time {
- offset := int(time.Monday - now.Weekday())
- if offset > 0 {
- offset = -6
- }
- offset += 6
-
- weekStart := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.Local).AddDate(0, 0, offset)
- return weekStart
- }
|