使用Epoch时间戳创建活动模型日期时间

时间:2014-07-31 16:52:37

标签: ruby-on-rails ruby datetime activerecord epoch

我有一个移动应用程序可以通过使用SimpleEvent模型的标准路由向Post Rails应用程序发送Post请求来创建事件。模型的重要部分在模式中看起来如此:

create_table "simple_events", force: true do |t|
    t.datetime "start_date",   null: false
    t.datetime "end_date",     null: false
end

应用程序发送浮点值以指示时间是最简单的,因为这是它们在本地存储的方式。但是,当我尝试使用带有以下行的纪元时间戳在rails控制台中创建SimpleEvent时:

SimpleEvent.create("start_date"=> 1406815132.0, "end_date"=> 1406815132.0)

我收到此错误:

ArgumentError: argument out of range
    from /Users/ataylor/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.4/lib/active_support/values/time_zone.rb:289:in `initialize'
    from /Users/ataylor/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.4/lib/active_support/values/time_zone.rb:289:in `new'
    from /Users/ataylor/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.4/lib/active_support/values/time_zone.rb:289:in `parse'
    from /Users/ataylor/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.4/lib/active_support/core_ext/string/zones.rb:9:in `in_time_zone'
    from /Users/ataylor/.rvm/gems/ruby-2.1.1/gems/activerecord-4.1.4/lib/active_record/attribute_methods/time_zone_conversion.rb:37:in `start_date='
    from /Users/ataylor/.rvm/gems/ruby-2.1.1/gems/activerecord-4.1.4/lib/active_record/attribute_assignment.rb:45:in `public_send'
    from /Users/ataylor/.rvm/gems/ruby-2.1.1/gems/activerecord-4.1.4/lib/active_record/attribute_assignment.rb:45:in `_assign_attribute'
    from /Users/ataylor/.rvm/gems/ruby-2.1.1/gems/activerecord-4.1.4/lib/active_record/attribute_assignment.rb:32:in `block in assign_attributes'
    from /Users/ataylor/.rvm/gems/ruby-2.1.1/gems/activerecord-4.1.4/lib/active_record/attribute_assignment.rb:26:in `each'
    from /Users/ataylor/.rvm/gems/ruby-2.1.1/gems/activerecord-4.1.4/lib/active_record/attribute_assignment.rb:26:in `assign_attributes'
    from /Users/ataylor/.rvm/gems/ruby-2.1.1/gems/activerecord-4.1.4/lib/active_record/core.rb:455:in `init_attributes'
    from /Users/ataylor/.rvm/gems/ruby-2.1.1/gems/activerecord-4.1.4/lib/active_record/core.rb:198:in `initialize'
    from /Users/ataylor/.rvm/gems/ruby-2.1.1/gems/activerecord-4.1.4/lib/active_record/inheritance.rb:30:in `new'
    from /Users/ataylor/.rvm/gems/ruby-2.1.1/gems/activerecord-4.1.4/lib/active_record/inheritance.rb:30:in `new'
    from /Users/ataylor/.rvm/gems/ruby-2.1.1/gems/activerecord-4.1.4/lib/active_record/persistence.rb:33:in `create'
    from (irb):71
    from /Users/ataylor/.rvm/gems/ruby-2.1.1/gems/railties-4.1.4/lib/rails/commands/console.rb:90:in `start'
    from /Users/ataylor/.rvm/gems/ruby-2.1.1/gems/railties-4.1.4/lib/rails/commands/console.rb:9:in `start'
    from /Users/ataylor/.rvm/gems/ruby-2.1.1/gems/railties-4.1.4/lib/rails/commands/commands_tasks.rb:69:in `console'
    from /Users/ataylor/.rvm/gems/ruby-2.1.1/gems/railties-4.1.4/lib/rails/commands/commands_tasks.rb:40:in `run_command!'
    from /Users/ataylor/.rvm/gems/ruby-2.1.1/gems/railties-4.1.4/lib/rails/commands.rb:17:in `<top (required)>'
    from bin/rails:4:in `require'
    from bin/rails:4:in `<main>'2.1.1 :072 >

我尝试在rails源代码中挖掘可能的解释,但没有太多运气。我该怎么做才能允许从模型中的时间戳创建DateTimes?

2 个答案:

答案 0 :(得分:2)

如果您仍希望能够将start_dateend_date与正常时间对象或字符串一起使用,我会创建一些新方法,从时间串设置start_date / end_date:

class SimpleEvent < ActiveRecord::Base
  def start_ts=(ts)
    write_attribute :start_date, DateTime.strptime(ts.to_s, '%s')
  end

  def end_ts=(ts)
    write_attribute :end_date, DateTime.strptime(ts.to_s, '%s')
  end
end

使用它们:

SimpleEvent.create("start_ts"=>"1406815132.0", "end_ts"=>"1406815132.0")

现在,当您使用start_ts / end_ts方法创建SimpleEvent时,它将解析时间戳并适当地设置start_date / end_date。

答案 1 :(得分:0)

我建议通过添加额外的函数来保存日期时间,以将其转换为datetime和store。

class SimpleEvent < ActiveRecord::Base

  def self.save_time start_time, end_time
      self.create(start_time: Time.at(start_time).to_datetime, end_time: Time.at(end_time).to_datetime
  end
end

我们关心在模型中编写一个函数,以便我们可以将数据作为纪元时间自行读取。

class SimpleEvent < ActiveRecord::Base

   def started_at
      self.start_time.to_i
   end

   def end_at
      self.end_time.to_i
   end
end