1. 首页
  2. 主题
  3. Go标准库

关于 Time.Before 陷阱

Justin19960208 · · 4219 次点击
判断一个字符串 clock time 格式时间是否发生```穿越```(比当前时间晚) ``` func IsTimeThrough(clockTime string) bool { tm, err := time.Parse("2006年01月02日 15:04:05", clockTime) if err != nil { return false } if time.Now().Add(time.Minute * 10).Before(tm) { return true } return false } ``` 单体测试代码: ``` func IsTimeThrough(clockTime string) bool { tm, err := time.Parse("2006年01月02日 15:04:05", clockTime) if err != nil { return false } t1 := time.Now().Add(time.Minute * 10) fmt.Println(t1.Format("2006年01月02日 15:04:05")) fmt.Println(tm.Format("2006年01月02日 15:04:05")) var flag = false if t1.Before(tm) { fmt.Println("true") flag = true } else { fmt.Println("false") flag = false } return flag } ``` 测试结果: ``` 2018年08月04日 11:30:34 2018年08月04日 11:21:10 true ``` 查看 **time** 包源码注释找到: ``` go1.9.2 time/time.go L48 // If Times t and u both contain monotonic clock readings, the operations // t.After(u), t.Before(u), t.Equal(u), and t.Sub(u) are carried out // using the monotonic clock readings alone, ignoring the wall clock // readings. If either t or u contains no monotonic clock reading, these // operations fall back to using the wall clock readings. ``` 如果两个时钟都是 monotonic 模式,会忽略 wall 的值,如果有一个不是 mononotic,会使用 wall 来作为补偿。 通过 debug 发现 **Now** 生成的时钟是 ```monitonic```,传入的字符串转化的时钟不是 ```monotonic```(wall = 0)。 虽然有这样的限制,但是不能违反结果啊!!! 这算 BUG 吗? 贴相应的源码片段: ``` // nsec returns the time's nanoseconds. func (t *Time) nsec() int32 { return int32(t.wall & nsecMask) } // sec returns the time's seconds since Jan 1 year 1. func (t *Time) sec() int64 { if t.wall&hasMonotonic != 0 { return wallToInternal + int64(t.wall<<1>>(nsecShift+1)) } return int64(t.ext) } ``` ``` // Before reports whether the time instant t is before u. func (t Time) Before(u Time) bool { if t.wall&u.wall&hasMonotonic != 0 { return t.ext < u.ext } return t.sec() < u.sec() || t.sec() == u.sec() && t.nsec() < u.nsec() } ``` 如果这样的需求该自己作比较?
建议楼主把时区信息也打印出来,就知道是怎么回事了
#2
更多评论
Justin19960208
Insects awaken soon after the first day of spring.
上一个实现: ``` func IsTimeThrough(clockTime string) bool { tm, err := time.Parse(&#34;2006年01月02日 15:04:05&#34;, clockTime) if err != nil { return false } // as the restricted condition for time.Before() now := time.Now().Add(time.Minute * 10) nY, nM, nD := now.Date() tY, tM, tD := tm.Date() if tY &gt; nY { return true } else if tY &lt; nY { return false } // tY == nY if tM &gt; nM { return true } else if tM &lt; nM { return false } // tM == nM if tD &gt; nD { return true } else if tD &lt; nD { return false } // tD == nD nH, nMinute, nS := now.Clock() tH, tMinute, tS := tm.Clock() if tH &gt; nH { return true } else if tH &lt; nH { return false } // tH == nH if tMinute &gt; nMinute { return true } else if tMinute &lt; nMinute { return false } // tMinute == nMinute if tS &gt; nS { return true } return false } ```
#1
此楼正解,楼主代码中time.Parse得到时区0的时间,time.Now得到东八区时间。建议time.Parse解析时加上时区
#3

用户登录

没有账号?注册

今日阅读排行

    加载中

一周阅读排行

    加载中