Module: BSON::Time

Defined in:
lib/bson/time.rb

Overview

Note:

Ruby time can have nanosecond precision: Time.utc(2020, 1, 1, 0, 0, 0, 999_999_999/1000r) Time#usec returns the number of microseconds in the time, and if the time has nanosecond precision the sub-microsecond part is truncated (the value is floored to the nearest millisecond). MongoDB only supports millisecond precision; we truncate the sub-millisecond part of microseconds (floor to the nearest millisecond). Note that if a time is constructed from a floating point value, the microsecond value may round to the starting floating point value but due to flooring, the time after serialization may end up to be different than the starting floating point value. It is recommended that time calculations use integer math only.

Injects behaviour for encoding and decoding time values to and from raw bytes as specified by the BSON spec.

See Also:

Since:

  • 2.0.0

Defined Under Namespace

Modules: ClassMethods

Constant Summary collapse

BSON_TYPE =

A time is type 0x09 in the BSON spec.

Since:

  • 2.0.0

::String.new(9.chr, encoding: BINARY).freeze

Instance Method Summary collapse

Instance Method Details

#_bson_to_iObject

Since:

  • 2.0.0



93
94
95
96
97
98
99
100
101
# File 'lib/bson/time.rb', line 93

def _bson_to_i
  # Workaround for JRuby's #to_i rounding negative timestamps up
  # rather than down (https://github.com/jruby/jruby/issues/6104)
  if BSON::Environment.jruby?
    (self - usec.to_r/1000000).to_i
  else
    to_i
  end
end

#as_extended_json(**options) ⇒ Hash

Note:

The time is floored to the nearest millisecond.

Converts this object to a representation directly serializable to Extended JSON (github.com/mongodb/specifications/blob/master/source/extended-json.rst).

Parameters:

  • opts (Hash)

    a customizable set of options

Returns:

  • (Hash)

    The extended json representation.

Since:

  • 2.0.0



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/bson/time.rb', line 72

def as_extended_json(**options)
  utc_time = utc
  if options[:mode] == :relaxed && (1970..9999).include?(utc_time.year)
    if utc_time.usec != 0
      if utc_time.respond_to?(:floor)
        # Ruby 2.7+
        utc_time = utc_time.floor(3)
      else
        utc_time -= utc_time.usec.divmod(1000).last.to_r / 1000000
      end
      {'$date' => utc_time.strftime('%Y-%m-%dT%H:%M:%S.%LZ')}
    else
      {'$date' => utc_time.strftime('%Y-%m-%dT%H:%M:%SZ')}
    end
  else
    sec = utc_time._bson_to_i
    msec = utc_time.usec.divmod(1000).first
    {'$date' => {'$numberLong' => (sec * 1000 + msec).to_s}}
  end
end

#to_bson(buffer = ByteBuffer.new) ⇒ BSON::ByteBuffer

Note:

The time is floored to the nearest millisecond.

Get the time as encoded BSON.

Examples:

Get the time as encoded BSON.

Time.new(2012, 1, 1, 0, 0, 0).to_bson

Returns:

See Also:

Since:

  • 2.0.0



58
59
60
61
# File 'lib/bson/time.rb', line 58

def to_bson(buffer = ByteBuffer.new)
  value = _bson_to_i * 1000 + usec.divmod(1000).first
  buffer.put_int64(value)
end