Uploaded image for project: 'Ruby Driver'
  1. Ruby Driver
  2. RUBY-2145

bson 4.8.0 rounds Time during serialization to bson/extended json

    • Type: Icon: Bug Bug
    • Resolution: Fixed
    • Priority: Icon: Major - P3 Major - P3
    • bson-4.8.1
    • Affects Version/s: None
    • Component/s: BSON
    • None
    • Fully Compatible

      As of bson 4.8.0 `Time#to_f` is used to serialize Time, which is not sufficient and may lead into unexpected behaviour:

      IEEE 754 double is not accurate enough to represent the exact number of nanoseconds since the Epoch.

      Here's simple example:

      time = Time.utc(2020, 4, 20, 23, 59, 59, Rational(999_999_999, 1000))
      # => 2020-04-20 23:59:59 UTC
      
      Time.at(time.to_f).utc
      # => 2020-04-21 00:00:00 UTC
      

       
      The problem can be seen on bson v4.8.0:

      BSON::VERSION
      # => "4.8.0"
      
      time = Time.utc(2020, 4, 20, 23, 59, 59, Rational(999_999_999, 1000))
      # => 2020-04-20 23:59:59 UTC
      
      time.to_r
      # => (1587427199999999999/1000000000)
      
      Time.from_bson(time.to_bson)
      # => 2020-04-21 00:00:00 UTC
      
      Time.from_bson(time.to_bson).to_r
      # => (1587427200/1)
      

      Now, here's how bson-4.7.1 behaved:

      BSON::VERSION
      # => "4.7.1"
      
      time = Time.utc(2020, 4, 20, 23, 59, 59, Rational(999_999_999, 1000))
      # => 2020-04-20 23:59:59 UTC
      
      time.to_r
      # => (1587427199999999999/1000000000)
      
      Time.from_bson(time.to_bson)
      # => 2020-04-20 23:59:59 UTC
      
      Time.from_bson(time.to_bson).to_r
      # => (1587427199999/1000)
      

      In other words we were losing some precision before, but at least we were in the same day. The problem shines in Rails environment, where one might write query like this:

      SomeModel.where("created_at" => { "$gte" => date.beginning_of_day, "$lte" => date.end_of_day })
      

            Assignee:
            oleg.pudeyev@mongodb.com Oleg Pudeyev (Inactive)
            Reporter:
            alexey@zapparov.com Alexey Zapparov
            Votes:
            1 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: