Details
-
Bug
-
Resolution: Fixed
-
Major - P3
-
7.0.6, 7.1.0
Description
Given the following model:
class Person |
include Mongoid::Document
|
|
field :dob, type: Date |
end |
A user can query the dob field of this model using a Time value.
Time.now |
# => 2020-04-22 15:27:39 -0400
|
|
Person.lte(dob: Time.now) |
# => selector: {"dob"=>{"$lte"=>2020-04-22 00:00:00 UTC}} |
During that query, the original Time is converted to a different Time instance equivalent to midnight UTC on the same day as the original Time.
However, when the same field is queried using a TimeWithZone value, the query is constructed using a TimeWithZone value equivalent to midnight on that same day in the current time zone.
Time.use_zone('Europe/Moscow') { Person.lte(dob: Time.zone.now) } |
# {"dob"=>{"$lte"=>Wed, 22 Apr 2020 00:00:00 MSK +03:00}} |
The behavior between these two classes is inconsistent. I believe that when TimeWithZone values are used to query Date fields, a TimeWithZone equivalent to midnight on that day in UTC should be used as the query value.
The original ticket description is below:
The following spec used to pass up to and including Mongoid 7.0.5 and started failing with Mongoid 7.0.6:
require "spec_helper" |
|
describe "Date valued fields" do |
context "when the TimeZone is ahead of UTC" do |
around do |example| |
Time.use_zone('Europe/Moscow') do |
example.run
|
end |
end |
|
let!(:match) do |
Person.create(dob: Time.zone.today) |
end |
|
let!(:non_match) do |
Person.create(dob: Time.zone.tomorrow) |
end |
|
it "returns the matching documents" do |
expect(Person.lte(dob: Time.zone.now)).to match_array([match]) |
end |
end |
|
context "when the TimeZone is trailing UTC" do |
around do |example| |
Time.use_zone('America/New_York') do |
example.run
|
end |
end |
|
let!(:match) do |
Person.create(dob: Time.zone.today) |
end |
|
let!(:non_match) do |
Person.create(dob: Time.zone.yesterday) |
end |
|
it "returns the matching documents" do |
expect(Person.gte(dob: Time.zone.now.beginning_of_day)).to match_array([match]) |
end |
end |
end |
The reason is the introduction of mongo/active_support:
In the first case we try to match 2020-03-12 with Mongoid's selector
{ "dob" => {"$lte"=>Thu, 12 Mar 2020 00:00:00 MSK +03:00} } |
which is equivalent to
{ "dob" => {"$lte"=>Wed, 11 Mar 2020 21:00:00 UTC} } |
The match will succeed if we expand 2020-03-12 into Thu, 12 Mar 2020 00:00:00 MSK +03:00 and fail if we interpret it as Thu, 12 Mar 2020 00:00:00 UTC.
Attachments
Issue Links
- is related to
-
RUBY-2179 Document that dates are serialized as midnight in UTC
-
- Closed
-
- links to