Time.utc(.) with a 1 ns difference yields "equal" times

Hi,

The us (microsecond) fractions of these 2 times are 1 ns (nanosecond)
off,
but the time are created with seemingly equal nsec values, thus leading
to
“equal” times.

In my app, this then causes a Dbd::OutOfOrderError
(Reading back a 1 M lines (dense) facts file with jruby triggers Dbd::OutOfOrderError. · Issue #1 · petervandenabeele/dbd · GitHub)

Probably something with the internal calculation of the usec value
that does not keep the Rational type ?

The source code is here:

The 2 consecutive rows that cause the error are:

2013-06-30 14:56:14.263031604 UTC

2013-06-30 14:56:14.263031605 UTC

Clearly different and monotonically increasing, but the JRuby
processing of the time incorrectly reports “equal” time.

jruby-1.7.4 :035 > h1[:sec_fraction] * 1_000_000_000
=> (263031604/1)
jruby-1.7.4 :036 > h2[:sec_fraction] * 1_000_000_000
=> (263031605/1)

jruby-1.7.4 :037 > time_hash = h1
=> {:year=>2013, :mon=>6, :mday=>30, :hour=>14, :min=>56, :sec=>14,
:sec_fraction=>(65757901/250000000), :zone=>“UTC”, :offset=>0}
jruby-1.7.4 :038 > td1 = Time.utc(time_hash[:year],
jruby-1.7.4 :039 > time_hash[:mon],
jruby-1.7.4 :040 > time_hash[:mday],
jruby-1.7.4 :041 > time_hash[:hour],
jruby-1.7.4 :042 > time_hash[:min],
jruby-1.7.4 :043 > time_hash[:sec],
jruby-1.7.4 :044 > time_hash[:sec_fraction] *
1_000_000)
=> 2013-06-30 14:56:14 UTC

jruby-1.7.4 :045 > time_hash = h2
=> {:year=>2013, :mon=>6, :mday=>30, :hour=>14, :min=>56, :sec=>14,
:sec_fraction=>(52606321/200000000), :zone=>“UTC”, :offset=>0}
jruby-1.7.4 :046 > td2 = Time.utc(time_hash[:year],
jruby-1.7.4 :047 > time_hash[:mon],
jruby-1.7.4 :048 > time_hash[:mday],
jruby-1.7.4 :049 > time_hash[:hour],
jruby-1.7.4 :050 > time_hash[:min],
jruby-1.7.4 :051 > time_hash[:sec],
jruby-1.7.4 :052 > time_hash[:sec_fraction] *
1_000_000)
=> 2013-06-30 14:56:14 UTC

jruby-1.7.4 :053 > td1 == td2
=> true ####################### This should be false

jruby-1.7.4 :057 > td1.nsec
=> 263031604
jruby-1.7.4 :058 > td2.nsec
=> 263031604 ################### This explains, the nsec value is the
same as for td1

/Users/peter_v/dbd $ ruby -v
jruby 1.7.4 (1.9.3p392) 2013-05-16 2390d3b on Java HotSpot™ 64-Bit
Server VM 1.6.0_45-b06-451-11M4406 [darwin-x86_64]

/Users/peter_v/dbd $ uname -a
Darwin Peters-MacBook-Pro-2.local 12.4.0 Darwin Kernel Version 12.4.0:
Wed
May 1 17:57:12 PDT 2013; root:xnu-2050.24.15~1/RELEASE_X86_64 x86_64

(bug originally popped up on Linux x64, now confirmed on Mac OS X).

How could I fix or work-around this ?

I could take a distance of at least 2 nano seconds between consecutive
times, but that
seems a bit lame since Rational numbers are used for the microsecond
offset, so I hoped
this to be exact ?

Because of a problem I face with installing jruby-head on rvm (on Mac
and
Linux),
I am unable to test this issue on jruby-head. Sorry for that …

Thanks for any insights,

@peter_v

On Jul 1, 2013, at 7:10 PM, Peter V.
[email protected] wrote:

that does not keep the Rational type ?
2013-06-30 14:56:14.263031605 UTC
jruby-1.7.4 :037 > time_hash = h1
jruby-1.7.4 :045 > time_hash = h2
jruby-1.7.4 :053 > td1 == td2
/Users/peter_v/dbd $ uname -a
Darwin Peters-MacBook-Pro-2.local 12.4.0 Darwin Kernel Version 12.4.0: Wed May
1 17:57:12 PDT 2013; root:xnu-2050.24.15~1/RELEASE_X86_64 x86_64

(bug originally popped up on Linux x64, now confirmed on Mac OS X).

Looks like nsec rounding is happening at the scale that we don’t want.

How could I fix or work-around this ?

Besides fixing and not relying on nanosecond precision on a non-RT
system, I can’t think of any.

I opened a ticket. Time#nsec rounding is happening at a place we don't want. · Issue #843 · jruby/jruby · GitHub