在Ruby 2.1.2中,我可以同时成功地比较Time.parse
和Time.utc
的结果,并返回预期的true
:
Time.parse("2015-02-09T22:38:43Z") == Time.utc(2015, 2, 9, 22, 38, 43)
=> true
但是,当第二个值不是整数时,同样的比较会违反直觉返回false
:
Time.parse("2015-02-09T22:38:43.1Z") == Time.utc(2015, 2, 9, 22, 38, 43.1)
=> false
尽管事实上第二个值仍然是整数并且仍然是等价的:
Time.parse("2015-02-09T22:38:43.1Z").sec
=> 43
Time.utc(2015, 2, 9, 22, 38, 43.1).sec
=> 43
Time.parse("2015-02-09T22:38:43.1Z").sec == Time.utc(2015, 2, 9, 22, 38, 43.1).sec
=> true
此外,在相同方法的连续调用之间的比较结果为true
:
Time.parse("2015-02-09T22:38:43.1Z") == Time.parse("2015-02-09T22:38:43.1Z")
=> true
Time.utc(2015, 2, 9, 22, 38, 43.1) == Time.utc(2015, 2, 9, 22, 38, 43.1)
=> true
为什么会这样?这是一个错误,还是我错过了什么?
答案 0 :(得分:5)
Ruby在比较时间时比较小数秒和秒。由于某种原因,您的时间会收到不同的小数秒:
Time.parse("2015-02-09T22:38:43.1Z").subsec
# => (1/10)
Time.utc(2015, 2, 9, 22, 38, 43.1).subsec
# => (14073748835533/140737488355328)
答案 1 :(得分:-1)
我相信你遇到了一个精确的问题。整数秒比较的原因是由于整数的精度,Ruby在解析后的版本上为你执行了.to_i
。
Time类的基础是一个整数,它表示一个非常精确的整数,并且解析和显式值的处理方式可能不同,从而导致出现问题。如果亚秒级精度对您来说并不重要,那么最好比较秒:
Time.parse("2015-02-09T22:38:43.1Z").to_i == Time.utc(2015, 2, 9, 22, 38, 43.1).to_i
在上面的例子中,您将比较自Unix时代(1970年1月1日)以来的秒数
另一种选择是创建一个在一定精度内进行两次比较的函数。许多单元测试框架都提供了该功能。基本上如果T1 == T2在0.1秒内,这就足够了。
进行“内部”比较的最简单方法是:
def within(time1, time2, precision)
return (time1 - time2).abs < precision
end
注意:上述内容适用于时间,浮点和分数。