Skip to content

Commit

Permalink
Fix issue #308 - ensure milliseconds are preserved with time values
Browse files Browse the repository at this point in the history
  • Loading branch information
kpshek committed Feb 13, 2012
1 parent 6ca8580 commit b43549f
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 11 deletions.
3 changes: 1 addition & 2 deletions lib/mongo_mapper/extensions/time.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ def to_mongo(value)
else
time_class = ::Time.try(:zone).present? ? ::Time.zone : ::Time
time = value.is_a?(::Time) ? value : time_class.parse(value.to_s)
# strip milliseconds as Ruby does micro and bson does milli and rounding rounded wrong
at(time.to_i).utc if time
at(time.to_f).utc if time # ensure milliseconds are preserved with to_f (issue #308)
end
end

Expand Down
10 changes: 5 additions & 5 deletions test/functional/test_timestamps.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,16 @@ class TimestampsTest < Test::Unit::TestCase

should "set updated_at on document update but leave created_at alone" do
doc = @klass.create(:first_name => 'John', :age => 27)
old_created_at = doc.created_at
old_updated_at = doc.updated_at
old_created_at = doc.created_at.to_f

Timecop.freeze(Time.now + 5.seconds) do
new_updated_at = Time.now + 5.seconds
Timecop.freeze(new_updated_at) do
@klass.update(doc._id, { :first_name => 'Johnny' })
end

doc = doc.reload
doc.created_at.should == old_created_at
doc.updated_at.should_not == old_updated_at
doc.created_at.to_f.should be_close(old_created_at, 0.001)
doc.updated_at.to_f.should be_close(new_updated_at.to_f, 0.001)
end
end
end
8 changes: 4 additions & 4 deletions test/unit/test_extensions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ class SupportTest < Test::Unit::TestCase
end

should "be time to milliseconds if string" do
Time.to_mongo('2000-01-01 01:01:01.123456').to_f.should == Time.local(2000, 1, 1, 1, 1, 1, 0).utc.to_f
Time.to_mongo('2000-01-01 01:01:01.123456').to_f.should be_close(Time.local(2000, 1, 1, 1, 1, 1, 123456).utc.to_f, 0.0000001)
end

should "be time in utc if time" do
Expand All @@ -301,18 +301,18 @@ class SupportTest < Test::Unit::TestCase
context "Time.to_mongo with Time.zone" do
should "be time to milliseconds if time" do
Time.zone = 'Hawaii'
Time.to_mongo(Time.zone.local(2009, 8, 15, 14, 0, 0, 123456)).to_f.should == Time.utc(2009, 8, 16, 0, 0, 0, 0).to_f
Time.to_mongo(Time.zone.local(2009, 8, 15, 14, 0, 0, 123456)).to_f.should be_close(Time.utc(2009, 8, 16, 0, 0, 0, 123456).to_f, 0.0000001)
Time.zone = nil
end

should "be time to milliseconds if string" do
Time.zone = 'Hawaii'
Time.to_mongo('2009-08-15 14:00:00.123456').to_f.should == Time.utc(2009, 8, 16, 0, 0, 0, 0).to_f
Time.to_mongo('2009-08-15 14:00:00.123456').to_f.should be_close(Time.utc(2009, 8, 16, 0, 0, 0, 123456).to_f, 0.0000001)
Time.zone = nil
end

should "not round up times at the end of the month" do
Time.to_mongo(Time.now.end_of_month).to_i.should == Time.now.end_of_month.utc.to_i
Time.to_mongo(Time.now.end_of_month).to_f.should be_close(Time.now.end_of_month.utc.to_f, 0.0000001)
end

should "be nil if blank string" do
Expand Down
5 changes: 5 additions & 0 deletions test/unit/test_time_zones.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ class TimeZonesTest < Test::Unit::TestCase
end
end

should "preserve milliseconds" do
doc = @document.new(:created_at => '2011-02-12 16:01:02.543Z')
doc.created_at.should be_close(Time.parse('2011-02-12 16:01:02.543Z'), 0.0000001)
end

should "work without Time.zone" do
Time.zone = nil

Expand Down

0 comments on commit b43549f

Please sign in to comment.