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



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

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

应用程序发送浮点值来指示时间是最简单的,因为这就是它们在本地存储的方式。但是,当我尝试在rails控制台中使用以下行的epoch时间戳创建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?

如果您仍然希望能够将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。

我建议通过添加一个额外的函数来保存日期时间,将其转换为日期时间并存储。

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

我们关心在模型本身中编写一个函数,这样我们就可以将数据读取为epoch时间本身。

class SimpleEvent < ActiveRecord::Base
   def started_at
      self.start_time.to_i
   end
   def end_at
      self.end_time.to_i
   end
end 

最新更新