我是一个新手,真的陷入了红宝石中不同的时间和日期格式。 到现在为止,我已经想出了如何解决这些问题。在这种情况下,我正在使用
find_or_initialize_by_sessiondate_and_person_id()并且它总是创建一个新记录,因为(显然)它不能识别从数据库中提取的日期与提供的日期相同。我正在从CSV文件中读取数据,输入如下:
Fri Apr 22 15:09:00 2011
活动记录不会抱怨这种格式 - 它将它放在数据库的日期时间字段中(SQLlite,但我希望解决方案适用于其他数据库)就好了。我尝试在输入中添加一个时区,如下所示:
createdate = DateTime.strptime(record_split[ 4 ].chomp + " UTC","%a %b %e %T %Y %Z"
session = Session.find_or_initialize_by_sessiondate_and_person_id(createdate, person.id)
if session.new_record?
puts "new record for #{person.name}, #{createdate.inspect}, #{session.sessiondate.inspect}"
输出如下:
new record for Mickey Mouse, Fri, 22 Apr 2011 15:09:00 +0000, Fri, 22 Apr 2011 15:09:00 UTC +00:00
这看起来和我的日期/时间相同,为什么ActiveRecord会创建新记录?
答案 0 :(得分:1)
我对发生的事情感到有点困惑。从你的例子来看,最让我担忧的事实是“2010年10月5日星期二19:43:23”正在被修改为“星期五,2011年4月22日15:09:00 +0000”(除非你使用的是不同的每个例子的日期......)
为了让自己更轻松,最好只使用Time.parse
而不是DateTime.strptime
:
ree-1.8.7-2010.02 > Time.parse("Tue Oct 5 19:43:23 2010")
=> Tue Oct 05 19:43:23 +1100 2010
另一件需要考虑的事情是,在内部,Rails 3将所有时间戳存储为UTC;然后它会在默认的时区中即时显示该时间。
最后,根据原始时间戳字段的生成方式(即Time.now vs解析字符串),您可能会遇到精度问题。如果使用Time.now填充createdate
,您可能会发现它已经持有一个正确到微秒的值(例如:'19:43:23.34131'),与您的解析时间相比( '19:43:23.00000')并不完全相同。
答案 1 :(得分:0)
也许是因为person_id
不同?
此日期时间也略有不同:
Fri, 22 Apr 2011 15:09:00 +0000
vs
Fri, 22 Apr 2011 15:09:00 UTC +00:00
答案 2 :(得分:0)
以UTC格式存储日期总是一个好主意,因此您可以在模型中使用以下内容:
def sessiondate=(dt)
write_attribute(:sessiondate, Time.parse(dt).utc)
end
答案 3 :(得分:0)
您的DateTime.new ...在我的Rails 3.0.7上不起作用,但是可以通过其他方式向您提供建议,这是我在rails控制台中的测试:
ruby-1.9.2-p136 :028 > v = Video.new :title => "toto"
=> #<Video id: nil>
ruby-1.9.2-p136 :029 > v.save
=> true
ruby-1.9.2-p136 :030 > v
=> #<Video id: 507>
v.id = 507
ruby-1.9.2-p136 :032 > v.created_at = "Tue Oct 5 19:43:23 2010" #I use your datetime
=> "Tue Oct 5 19:43:23 2010"
ruby-1.9.2-p136 :033 > v.save
=> true
ruby-1.9.2-p136 :034 > v.created_at
=> Tue, 05 Oct 2010 19:43:23 UTC +00:00
ruby-1.9.2-p136 :035 > v2 = Video.find_or_initialize_by_created_at("Tue Oct 5 19:43:23 2010")
=> #<Video id: nil, ... , created_at: "2010-10-05 19:43:23", ... >
ruby-1.9.2-p136 :039 > v2.save
=> true
ruby-1.9.2-p136 :040 > v2
=> #<Video id: 508>
新记录,v.id = 507,v2 = 508!
... > v3 = Video.
find_or_initialize_by_created_at("Tue Oct 5 19:43:23 2010".to_datetime)
现在使用日期字符串
上的String.to_datetime方法 => #<Video id: 507> # We get v !!!
ruby-1.9.2-p136 :043 > v == v3
=> true
p.s:这是一个I18n应用程序,这就是为什么你没有看到title属性。
答案 4 :(得分:0)
似乎SQLite和Active Record没有很好地沟通日期时间的类型。