Search code examples
rubysqlitedatamappersqlite3-rubyruby-2.1

data_mapper: Can't save Time object


I am attempting to persist an object that has a Time-type field. On create, I attempt to set the sleep_value to a valid Time object but the save seems to fail silently (even though raise_on_save_failure is set to true).

If I try to search for the object via Sleep.all or Sleep.get(1), i am getting an error argument out of range.

The only value I can pass it to make it persist is Time.now(). If I do a Sleep.all, that object with sleep_time => Time.now is returned.

gems:    
data_mapper (1.2.0)   
sqlite3 (1.3.10)


require 'sqlite3'
require 'data_mapper'

DataMapper::setup(:default, "sqlite3://#{Dir.pwd}/test.db")

DataMapper::Model.raise_on_save_failure = true

class Sleep

    include DataMapper::Resource
    property :id,           Serial
    property :sleep_time,   Time

end

DataMapper.finalize.auto_migrate!

Sleep.create(:sleep_time => Time.new(2015, 10, 1))

Sleep.all

UPDATE: I have done a bit more trial and error and have found the following values are compatible with the time field (changed the name from sleep_time to st)

Sleep.create(:st => (Time.now - 1))
Sleep.create(:st => Time.at((Time.now - Time.at(1000))))

And the following values do not save (no error is thrown but records are nt persisted)

Sleep.create(:st => Time.new(2015, 10, 1, 2, 2, 2, "+02:00"))
Sleep.create(:st => Time.new(2002))
Sleep.create(:st => Time.new((Time.now - Time.new(2002)))) #out of range
Sleep.create(:st => Time.at(2)) #out of range

Solution

  • I used the fact that I could use with Time.now() and made this helper method. I call it to save my Time properties.

    def self.convert_to_dm_friendly_time(target_time)

    today = Time.now
    return today + target_time.to_i - today.to_i #basically starting the object from today and then taking today out.
    
    end
    

    Damn, this was an ugly solution. Surely there is an easier way?