2017-10-17 62 views
4

我试图用存储在Rails中精确到毫秒的时间标记,但价值被抬高了,当我取回从数据库中记录:存储时间毫秒的Rails

record.time_stamp = Time.utc(2017,1,1,1,1,1.35) 

入住时间保存前:

record.time_stamp.strftime('%H:%M:%S.%L') 
=> "01:01:01.350" 
record.time_stamp.usec 
=> 350000 
record.time_stamp.to_f 
=> 1483232461.35 

保存和重新加载:

保存后
record.save! 
record.reload 

入住时间:

record.time_stamp.strftime('%H:%M:%S.%L') 
=> "01:01:01.006" 
record.time_stamp.usec 
=> 6108 
record.time_stamp.to_f 
=> 1483232461.0061078 
record.read_attribute_before_type_cast("time_stamp") // Read raw value before type casting 
=> "2017-01-01 01:01:01.35" 

不知道这里发生了什么事。存储在数据库中的毫秒值是正确的,类型转换前的原始值也是如此(参见最后一行),当它重新投入Ruby时间时,它就会被忽略。

注:

规格:的Rails/ActiveRecord的4.2.6,红宝石2.3.0,9.5.0的Postgres,OSX)


UPDATE:
我只是想再现这个问题一个与我目前的应用程序完全相同的rails/ruby​​/postgres版本的新的rails应用程序,并且无法做到这一点!而且,由于其他人也无法复制,这意味着这是我的应用程序明确具体的东西,我需要进一步挖掘以试图隔离造成这种情况的原因......当我获得更多信息时会更新。

+0

这可能是一个时区的事情。您是否检查了与UTC时间戳相对的值?你可能会在'UTC'节省时间并检索'GMT'? – Cyzanfar

+0

@Cyzanfar - 查看更新,UTC中的相同内容。 (无论如何,时区差异不会影响秒/毫秒吧?) – Yarin

+0

正确它不应该影响它......让我对我的结局做一些研究。让我知道是否以及何时找到解决方案。这是一个有趣的问题。 – Cyzanfar

回答

-1

检查数据库/表时区vs Rails时区vs系统时区,看起来您在保存的内容和返回的内容之间有5小时的差异,这看起来与UTC和EST之间的差异相对应。

+0

这不是时区问题。问题是关于以毫秒为单位的差异,而不是几个小时。 – Yarin

+0

您是否尝试存储以毫秒(* 1000)为单位的时间戳,然后是Time.at(ts/1000)?我注意到有时显然随机值会变成四舍五入整数(或者,不是那么多的整数,考虑到他们仍然会有一个尾随.00001或什么时候投给to_f) –

1

我不能使用Rails 4.2.65.0.5重现问题(和Ruby 2.3.1,Postgres的9.6.4

# Gemfile 
ruby '2.3.1' 
gem 'rails', '4.2.6' 
gem 'pg' 
require 'active_record' 

# example.rb 
class Record < ActiveRecord::Base 
    establish_connection \ 
    adapter: 'postgresql', 
    database: 'try_timestamp', 
    username: 'postgres' 

    connection.create_table table_name, force: true do |t| 
    t.datetime :time_stamp 
    end 
end 

time_stamp = Time.utc 2017,1,1,1,1,1.35 
record  = Record.new time_stamp: time_stamp 

p record.time_stamp.strftime('%H:%M:%S.%L') 
p record.time_stamp.usec 
p record.time_stamp.to_f 

record.save! 
record.reload 

p record.time_stamp.strftime('%H:%M:%S.%L') 
p record.time_stamp.usec 
p record.time_stamp.to_f 


# terminal command 
❯ createdb try_timestamp 
❯ bundle install 
❯ bundle exec ruby example.rb 
"01:01:01.350" 
350000 
1483232461.35 
"01:01:01.350" 
350000 
1483232461.3500001 

你能运行这个例子,并告诉该问题是否明确的Rails应用程序再现?

+0

我也无法重现这个问题。 –

+0

@itsnikolay果然,我只是尝试在一个新的rails应用程序中重现此问题*与我的当前应用程序完全相同的rails/ruby​​/postgres版本*,并且无法做到这一点!看起来我需要进一步挖掘,以尝试隔离是什么导致此.. – Yarin

+0

@Yarin尝试调试,一步一步从您的应用程序中添加每个gem Gemfile在我的示例应用程序Gemfile ^^。因为一些宝石可以为自己的目的打补丁日期。如果你不能用完整的宝石列表来重现它,那么你应该开始在你的代码中查找问题(从config/initializers等开始搜索,直到跟踪)。 – itsnikolay