github.com/aquayi/gokit@v0.0.0-20170805152833-88827a405d9b/time.go (about) 1 package GoKit 2 3 import ( 4 "errors" 5 "fmt" 6 "log" 7 "time" 8 ) 9 10 // DateOf 返回会把 timestamp 普通的日期格式 11 // 例如:把 1136185384 转换成 "2006-01-02 15:03:04 +0800 CST" 12 func DateOf(t int64) string { 13 return time.Unix(t, 0).String() 14 } 15 16 // WaitFunc 返回 一个 cycleCh chan<- time.Duration 和 一个 Wait 函数 17 // 如果 cycleCh <- d ,则 Wait() 的sleep时间被修改为 d 18 // sleep时间的修改会立即生效,不用等到此waitDuration结束。 19 // 例如:当100秒的waitDuration时间已过51秒时,把waitDuration修改为50秒,程序会立刻结束。 20 // 不用等到100秒才结束。 21 // 例如:100秒的waitDuration在结束前,把waitDuration修改为200秒, 22 // 此次Wait()会sleep 200秒才结束。 23 // 24 // checkCycle是检查是否到期的时间段,也是最小等待时间段。 25 // 26 // 当checkCycle较大时,Wait()的sleep时间会和waitDuration,有较大的差距, 27 // 程序的实际等待时间,总是 checkCycle × int(waitDuration/checkCycle + 1) 28 func WaitFunc(checkCycle time.Duration, name string) (chan<- time.Duration, func()) { 29 cycleCh := make(chan time.Duration, 7) 30 beginTime := time.Now() 31 waitDuration := checkCycle 32 33 return cycleCh, func() { 34 35 for { 36 select { 37 case waitDuration = <-cycleCh: 38 if waitDuration <= checkCycle { 39 log.Printf("WARNING: %s的 等待时间 <= 检查周期 ,程序只会按照检查周期来等待。", name) 40 } 41 log.Printf("INFO: %s的 等待时间 已经修改为:%s", name, waitDuration) 42 default: 43 } 44 45 // 把判断是否结束的语句,放在最后,很有必要。 46 // 因为很有可能,wait()的调用周期总是大于waitDuration 47 // 而导致总是无法进入for循环,来改变waitDuration的值 48 // 特别是第一个waitDuration的值为checkCycle,总是比较小的。 49 50 if time.Now().Before(beginTime.Add(waitDuration)) { 51 time.Sleep(checkCycle) 52 } else { 53 break 54 } 55 } 56 57 beginTime = time.Now() 58 } 59 } 60 61 //SleepFunc 返回一个等待sleep函数, 使程序暂停一个duration。 62 //SleepFunc是以上WaitFunc的简化版本,通常运用于API访问限制 63 //利用闭包,把beginTime变量包裹到了sleep函数内。 64 func SleepFunc(duration time.Duration) func() { 65 beginTime := time.Now() 66 return func() { 67 //无需判断,如果Sleep的时间为负,则不会Sleep。 68 time.Sleep(duration - time.Since(beginTime)) 69 beginTime = time.Now() 70 } 71 } 72 73 // ParseLocalTime 把string格式的时间,转换成time.time 74 // NOTICE: 我写这个函数的原因是 75 // 1. 添加更详解的错误说明。 76 // 2. 编写单元测试,查看是否真的转换成功了。 77 func ParseLocalTime(strTime string) (*time.Time, error) { 78 t, err := time.ParseInLocation("2006-01-02 15:04:05", strTime, time.Local) 79 if err != nil { 80 msg := fmt.Sprintf("无法把%s转换成time.time格式: %s", strTime, err) 81 return nil, errors.New(msg) 82 } 83 84 return &t, nil 85 }