Объект Ruby Time, преобразованный из float, не равен orignial Time object

time = Time.now
fvalue = time.to_f
return time == Time.at(fvalue)

Может кто-нибудь здесь объяснить, почему приведенное выше выражение возвращает false. Как создать новый объект Time из float, который соответствует исходной переменной времени?

Спасибо

Ответ 1

IEEE 754 double (который возвращается to_f) недостаточно точен, чтобы представлять точное время.

t1 = Time.now
f1 = t1.to_f
t2 = Time.at(f1)

# they look the same
t1.inspect #=> '2013-09-09 23:46:08 +0200'
t2.inspect #=> '2013-09-09 23:46:08 +0200'

# but double does not have enough precision to be accurate to the nanosecond
t1.nsec #=> 827938306
t2.nsec #=> 827938318
#                  ^^

# so they are different
t1 == t2 #=> false

Для сохранения точного времени выполните следующие действия:

t1 = Time.now
r1 = t1.to_r # value of time as a rational number
t2 = Time.at(r1)
t1 == t2 #=> true

Цитата из Time.to_r:

Эти методы предназначены для получения точной величины представляя наносекунды с эпохи. Вы можете использовать этот метод для преобразования времени в другую эпоху.