我正在Ruby 1.8.7上使用Rails 3.2.1和Jbuilder構建一個簡單的JSON API(1.9.x可能會幫助我,但我的託管提供者只有1.8.7)。Rails:JSON中的時間#to_f精度?
由於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
秒。注意額外的小數。
如此最佳地,時間戳應該用1個額外的十進制進行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,所以浮點數可以有有更高的精度。它會打破JS兼容性(因此JSON規範)添加另一個數字(十進制或其他),因爲我相信JS浮動無法處理。因此,也許我需要一個完全不同的方法......
你可以輸出時間爲字符串:'「#{updated_at.to_i}。#{updated_at.usec}」'? (好吧,根據需要在'usec'中加上前導零。) – millimoose 2012-02-04 01:12:28
是的,沒有。如果我輸出字符串,我可以做很多類似的事情。但我需要輸出一個浮點數。如果我創建一個字符串,然後運行'to_f',我又回到了開始的位置:精確度損失。 – Flambino 2012-02-04 01:43:53
你可以輸出BigDecimals而不是浮動嗎? JSON庫可能會將它們視爲數字。 – millimoose 2012-02-04 01:47:07