go的cron里面经典的取下一次时间
2018-06-01 02:07
295 查看
func (s *SpecSchedule) Next(t time.Time) time.Time { // General approach: // For Month, Day, Hour, Minute, Second: // Check if the time value matches. If yes, continue to the next field. // If the field doesn't match the schedule, then increment the field until it matches. // While incrementing the field, a wrap-around brings it back to the beginning // of the field list (since it is necessary to re-verify previous field // values) // 下一次每次取最近1s的时间 t = t.Add(1*time.Second - time.Duration(t.Nanosecond())*time.Nanosecond) // This flag indicates whether a field has been incremented. added := false // If no time is found within five years, return zero. yearLimit := t.Year() + 5 WRAP: if t.Year() > yearLimit { return time.Time{} } // Find the first applicable month. // If it's this month, then do nothing. //通过指数法逼近值,并通过从sec到min到hour到day到mon到year的不断逼近 for 1<<uint(t.Month())&s.Month == 0 { // If we have to add a month, reset the other parts to 0. if !added { added = true // Otherwise, set the date at the beginning (since the current time is irrelevant). t = time.Date(t.Year(), t.Month(), 1, 0, 0, 0, 0, t.Location()) } t = t.AddDate(0, 1, 0) // Wrapped around. if t.Month() == time.January { goto WRAP } } // Now get a day in that month. for !dayMatches(s, t) { if !added { added = true t = time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location()) } t = t.AddDate(0, 0, 1) if t.Day() == 1 { goto WRAP } } for 1<<uint(t.Hour())&s.Hour == 0 { if !added { added = true t = time.Date(t.Year(), t.Month(), t.Day(), t.Hour(), 0, 0, 0, t.Location()) } t = t.Add(1 * time.Hour) if t.Hour() == 0 { goto WRAP } } for 1<<uint(t.Minute())&s.Minute == 0 { if !added { added = true t = t.Truncate(time.Minute) } t = t.Add(1 * time.Minute) if t.Minute() == 0 { goto WRAP } } for 1<<uint(t.Second())&s.Second == 0 { if !added { added = true t = t.Truncate(time.Second) } t = t.Add(1 * time.Second) if t.Second() == 0 { goto WRAP } } return t }
代码里面最经典的还是这种位运算:
1<<uint(t.Month())&s.Month //转化为计算公式为: 2^t.Month & s.Month //比如t.Month = 3, s.Month = 4 2^t.Month = 8 > s.Month 并且此时与操作为0 //说明此时t.Month与s.Month差距不多,当t.Month=1的时候 2^t.Month = 2 此时与操作结果不为0 //当t.Month=2的时候 也是如此 //总结就是 2^t.Month > s.Month的时候操作结果为0,需要轮转到比它小很多的位置, //然后Month的更新再依赖于下面的day的更新
相关文章推荐
- ffmpeg,记一次录音文件信息里面码率,时间丢失的问题。
- 怎样花两年时间去面试一个人(对于我,重点是里面提及的经典书)
- 请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。
- Go语言中的时间格式
- 经典的间隔时间滚动新闻(图片),可控制滚动
- 一次经典的电话会议
- //深搜dfs//又做一次的经典题?//素数环------三I
- 有时间一天看一次
- Go笔记-时间
- 使用cron定时执行ubuntu里面的shell application
- C#里面比较时间大小三种方法
- mysql里面时间处理函数cast
- 求数组里面仅仅出现一次的数字的个数
- 【经典算法】:如何在一个函数里面返回多个值的实现
- Go语言 北京UTC+8 时间问题
- 推荐一款免费电脑打电话软件,只要注册一次就可以获得8分钟免费通话时间
- Quartz中时间参数说明 即Cron表达式
- C#里面比较时间大小三种方法
- 关于Parse字符串为时间一次被坑经历
- 50篇世界名著里面的50条经典名句