为什么某些时间比较会产生违反直觉的结果?
Why do certain Time comparisons have counterintuitive results?
在Ruby 2.1.2中,我可以成功地同时比较Time.parse
和Time.utc
的结果,returns预期的[=16] =]:
Time.parse("2015-02-09T22:38:43Z") == Time.utc(2015, 2, 9, 22, 38, 43)
=> true
然而,当第二个值不是整数时,这个相同的比较违反直觉 returns 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
为什么会这样?这是一个错误,还是我遗漏了什么?
Ruby比较时间时比较小数秒和秒。出于某种原因,您的时间收到不同的小数秒:
Time.parse("2015-02-09T22:38:43.1Z").subsec
# => (1/10)
Time.utc(2015, 2, 9, 22, 38, 43.1).subsec
# => (14073748835533/140737488355328)
我相信您 运行 陷入了一个精确的问题。整数秒比较起作用的原因是整数的精度,Ruby 为您对解析后的版本执行了 .to_i
。
时间的底层 class 是一个表示非常精确的整数的整数,解析值和显式值的处理方式可能完全不同,足以引起问题。如果亚秒精度对你来说不重要,那么最好比较秒:
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 秒内,就足够了。
进行 "within" 比较的最简单方法如下:
def within(time1, time2, precision)
return (time1 - time2).abs < precision
end
注意:以上适用于时间、浮点数和分数。
在Ruby 2.1.2中,我可以成功地同时比较Time.parse
和Time.utc
的结果,returns预期的[=16] =]:
Time.parse("2015-02-09T22:38:43Z") == Time.utc(2015, 2, 9, 22, 38, 43)
=> true
然而,当第二个值不是整数时,这个相同的比较违反直觉 returns 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
为什么会这样?这是一个错误,还是我遗漏了什么?
Ruby比较时间时比较小数秒和秒。出于某种原因,您的时间收到不同的小数秒:
Time.parse("2015-02-09T22:38:43.1Z").subsec
# => (1/10)
Time.utc(2015, 2, 9, 22, 38, 43.1).subsec
# => (14073748835533/140737488355328)
我相信您 运行 陷入了一个精确的问题。整数秒比较起作用的原因是整数的精度,Ruby 为您对解析后的版本执行了 .to_i
。
时间的底层 class 是一个表示非常精确的整数的整数,解析值和显式值的处理方式可能完全不同,足以引起问题。如果亚秒精度对你来说不重要,那么最好比较秒:
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 秒内,就足够了。
进行 "within" 比较的最简单方法如下:
def within(time1, time2, precision)
return (time1 - time2).abs < precision
end
注意:以上适用于时间、浮点数和分数。