Skip to content

Instantly share code, notes, and snippets.

@tjwallace
Created January 18, 2014 02:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tjwallace/8485160 to your computer and use it in GitHub Desktop.
Save tjwallace/8485160 to your computer and use it in GitHub Desktop.
From 2c6ea1df2198a25279f9d09832c901d42a41127c Mon Sep 17 00:00:00 2001
From: Jeff Wallace <jeff@zozi.com>
Date: Fri, 17 Jan 2014 14:12:18 -0800
Subject: [PATCH] Patch Time#== and Date#== to only check up to microsecond
equality
---
spec/lib/time_patch_spec.rb | 49 +++++++++++++++++++++++++++++++++++++++++++++
spec/support/time_patch.rb | 23 +++++++++++++++++++++
2 files changed, 72 insertions(+)
create mode 100644 spec/lib/time_patch_spec.rb
create mode 100644 spec/support/time_patch.rb
diff --git a/spec/lib/time_patch_spec.rb b/spec/lib/time_patch_spec.rb
new file mode 100644
index 0000000..1dd6c22
--- /dev/null
+++ b/spec/lib/time_patch_spec.rb
@@ -0,0 +1,49 @@
+require 'spec_helper'
+
+describe "Time patches" do
+
+ describe "for Time#==" do
+ let(:time1) { Time.at(0, 0.0) }
+ let(:time2) { Time.at(0, 0.5) }
+
+ it "ignores nanoseconds" do
+ expect(time1).to eq(time2)
+ end
+ end
+
+ describe "for ActiveSupport::TimeWithZone#==" do
+ let(:time1) { Time.at(0, 0.0).in_time_zone }
+ let(:time2) { Time.at(0, 0.5).in_time_zone }
+
+ it "ignores nanoseconds" do
+ expect(time1).to eq(time2)
+ end
+ end
+
+ describe "for DateTime#==" do
+ let(:date1) { DateTime.new(2000, 1, 1, 1, 1, Rational(1, 10000000)) }
+ let(:date2) { DateTime.new(2000, 1, 1, 1, 1, Rational(5, 10000000)) }
+
+ it "ignores nanoseconds" do
+ expect(date1).to eq(date2)
+ end
+ end
+
+ describe "for a mix of all 3 classes" do
+ let(:time1) { Time.utc(2000, 1, 1, 1, 1, 0, 0.0) }
+ let(:time2) { Time.utc(2000, 1, 1, 1, 1, 0, 0.5).in_time_zone }
+ let(:time3) { DateTime.new(2000, 1, 1, 1, 1, Rational(6, 10000000)) }
+
+ it "ignores nanoseconds" do
+ expect(time1).to eq(time2)
+ expect(time1).to eq(time3)
+
+ expect(time2).to eq(time1)
+ expect(time2).to eq(time3)
+
+ expect(time3).to eq(time1)
+ expect(time3).to eq(time2)
+ end
+ end
+
+end
diff --git a/spec/support/time_patch.rb b/spec/support/time_patch.rb
new file mode 100644
index 0000000..1f26a81
--- /dev/null
+++ b/spec/support/time_patch.rb
@@ -0,0 +1,23 @@
+# On linux (Circle CI) Time.now has nanosecond precision but on OSX it
+# only has microsecond precision. Postgresql stores time at microsecond
+# precision so timestamps generated in ruby (when creating a new record)
+# will not match what is stored in the database on linux.
+#
+# Also Time#to_f rounds up after using #end_of_day, so we have to use
+# the BigDecimal conversion.
+
+def _time_to_bigdecimal(time)
+ BigDecimal.new("#{time.to_i}.#{time.usec}")
+end
+
+class Time
+ def <=>(other_time)
+ _time_to_bigdecimal(self) <=> _time_to_bigdecimal(other_time)
+ end
+end
+
+class Date
+ def <=>(other_date)
+ self.to_time <=> other_date.to_time
+ end
+end
--
1.8.5.2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment