Я создаю простой JSON API с использованием Rails 3.2.1 и Jbuilder на Ruby 1.8.7 (1.9.x может помочь мне в этом, но у моего хостинг-провайдера только 1.8.7).
Поскольку потребитель API ожидает метки времени как числа с плавающей точкой, в настоящее время я просто делаю простые to_f
для атрибутов времени:
json.updated_at record.updated_at.to_f #=> 1328242368.02242
Но to_f
несет потерю точности. Это вызывает некоторые проблемы, когда клиент запрашивает записи, которые были изменены с данного момента времени, поскольку запрос SQL находит ту же запись, которую клиент использует для справки. То есть при попытке найти «более новые» записи, чем в приведенном выше примере, SQL-запрос (например, updated_at > Time.at(1328242368.02242)
) возвращает эту же запись, поскольку фактическое значение updated_at
является более точным и незначительно большим, чем заданная временная метка.
Фактически, record.updated_at.usec #=> 22425
или 0.022425
секунд. Обратите внимание на дополнительный десятичный.
Таким образом, оптимально, метка времени должна быть JSON'-указана с одним дополнительным десятичным знаком, например, 1328242368.022425, но я не могу найти способ, чтобы это произошло.
updated_at.to_i #=> 1328242368 # seconds
updated_at.usec #=> 22425 # microseconds
updated_at.to_f #=> 1328242368.02242 # precision loss
# Hacking around `to_f` doesn't help
decimals = updated_at.usec / 1000000.0 #=> 0.022425 # yay, decimals!
updated_at.to_i + decimals #=> 1328242368.02242 # dammit!
Я искал способы установить точность по умолчанию, но я в тупике. Есть идеи?
Редактировать: я должен добавить, что потребитель API не использует JavaScript, поэтому float может иметь более высокую точность. Это нарушило бы JS-совместимость (и, следовательно, спецификацию JSON), добавив еще одну цифру (десятичную или иную), поскольку, как я полагаю, поплавки JS не могут справиться с этим. Так что, возможно, мне нужен совершенно другой подход ...