我的iOS应用程序使用rails API,输出具有3位微秒精度的JSON格式日期,如下例所示。这将被解析并保存为相应的实体,NSDate保留了预期的3位精度:
{ "updated_at": "2015-02-24T22:37:57.683Z" }
当我将此日期发回API以查询记录时,数据库中的updated_at
字段似乎具有(至少)6位数的精度:
>> my_model.update_at.strftime('%Y-%m-%d %H:%M:%S.%N')
>> 2015-02-24 22:37:57.683977000
这意味着每次我查询
>> ios_date = json_hash["updated_at"]
>> Model.where("updated_at > ?", ios_date)
我在应用的数据库中已经存在一条记录。
我知道我可以在ios_date
添加半秒来解决此问题,但这显然是一个黑客攻击。
在这种情况下,有人可以推荐什么是最合适的行动方案吗?
TIA
答案 0 :(得分:1)
在这种情况下,我认为最好的方法是存储在数据库中并输出为JSON 完全相同的东西,以避免任何转换或舍入问题的需要。我假设你想要保留3位微秒的精确日期,我只是将你的数据库配置为以这种精度存储日期。
您可以使用迁移来修改:created_at和:updated_at字段的精度,如下所示:
class MicrosecondsMigration < ActiveRecord::Migration
def up
change_column :your_table, :created_at, :datetime, precision: 3
change_column :your_table, :updated_at, :datetime, precision: 3
end
def down
change_column :your_table, :created_at, :datetime
change_column :your_table, :updated_at, :datetime
end
end
我相信这将适用于主要数据库。 Check this commit at Rails为Postgresql添加了支持。如果您使用的是MySQL,请注意只有MySQL 5.6.4 and above支持DATETIME的精度高于一秒。这不是你的问题,你已经说过你的数据库存储了6位数的精确日期时间,但我认为这值得注意。
我可以想到其他方法,虽然没有一种看起来比上述方法更好,但它们也值得注意:
ios_date
添加几毫秒,感觉更加丑陋。答案 1 :(得分:0)
即使更改created_at和updated_at的精度限制的选项是一个有效选项,我发现最干净/最“Railsy”的解决方案是获得to_json
的输出以匹配数据库精度。
这可以通过一行代码来实现:
ActiveSupport::JSON::Encoding.time_precision = 6
实际上,这并没有真正解决问题,因为时间戳的基础存储类型是浮点数,因此某些时间比较仍然失败。
最后,根据@dgilperez在本页的回答,降低精确度是我的选择。