Skip to content

Display nanosecond precision for Time and DateTime #430

Merged
merged 1 commit into from Jan 22, 2014

3 participants

@tjwallace

This is a follow up to #331 and #416.

Linux creates Time objects with nanosecond precision so only displaying microseconds can hide the differences between two objects.

@tjwallace

It looks like some Ruby implementations cannot handle nanosecond input. I will revert the spec changes.

@myronmarston
RSpec member

Thanks for the PR :). This is failing on 1.8.7 because there's no nsec method. I think it would be good to use (and test) nsec on 1.9+ but stick to usec on 1.9. For things like that we often have two different method defs, and conditionally define the appropriate one based on the ruby environment:

if Time.method_defined?(:nsec)
  def format_time(time)
    time.strftime("#{TIME_FORMAT}.#{"%09d" % time.nsec} %z")
  end

  DATE_TIME_FORMAT = "%a, %d %b %Y %H:%M:%S.%9N %z"
else # for 1.8.7
  def format_time(time)
    time.strftime("#{TIME_FORMAT}.#{"%06d" % time.usec} %z")
  end

  DATE_TIME_FORMAT = "%a, %d %b %Y %H:%M:%S.%6N %z"
end
@tjwallace

@myronmarston great call, changes made in 9550c0c

@myronmarston
RSpec member

Do you mind squashing your commits into one?

@thomas-holmes thomas-holmes and 2 others commented on an outdated diff Jan 19, 2014
lib/rspec/matchers/built_in/eq.rb
- # Append microseconds to the default format string
- def format_time(time)
- time.strftime("#{TIME_FORMAT}.#{"%06d" % time.usec} %z")
+
+ if Time.method_defined?(:nsec)
+ def format_time(time)
+ time.strftime("#{TIME_FORMAT}.#{"%09d" % time.nsec} %z")
+ end
+
+ DATE_TIME_FORMAT = "%a, %d %b %Y %H:%M:%S.%9N %z"
+ else # for 1.8.7
+ def format_time(time)
+ time.strftime("#{TIME_FORMAT}.#{"%06d" % time.usec} %z")
+ end
+
+ DATE_TIME_FORMAT = "%a, %d %b %Y %H:%M:%S.%6N %z"
@thomas-holmes
RSpec member

You don't need to don't specify %6N or %9N but just %N instead it will go out to 9 digits by default (on my system). Depending on the platform this may or may not ever have digits there.

While not a huge deal it would simplify the conditional a bit.

On 1.8.7 you can also get more digits out of a Time object by using #to_f by doing something like "%.9f" % Time.now.to_f". Granted, this will probably be susceptible to standard float precision.

@myronmarston
RSpec member
myronmarston added a note Jan 19, 2014

Given time doesn't expose the nanoseconds on 1.8.7., is the to_f representation out to 9 digits even accurate?

@thomas-holmes
RSpec member

On my platform I don't get more precision on 1.8.7

# 1.8.7
>> "%.9f" % Time.at(10, 0).to_f
=> "10.000000000"
>> "%.9f" % Time.at(10, 10000).to_f
=> "10.010000000"
>> "%.9f" % Time.at(10, 10000.10).to_f
=> "10.010000000"

# 1.9.3
>> "%.9f" % Time.at(10, 0).to_f
=> "10.000000000"
>> "%.9f" % Time.at(10, 10000).to_f
=> "10.010000000"
>> "%.9f" % Time.at(10, 10000.10).to_f
=> "10.010000100"
>> "%.9f" % Time.at(10, 10000.123456).to_f
=> "10.010000123"
>> Time.at(10, 10000.123456).nsec
=> 10000123
@tjwallace
tjwallace added a note Jan 20, 2014

From this comment in the source, and like @thomas-holmes suggested, the value returned by #to_f is not accurate enough for nanoseconds, and it's recommended to use #nsec.

In 1.8.7:

[35] pry(main)> t = Time.at(999999999, 999999.999)
=> Sat Sep 08 18:46:39 -0700 2001
[36] pry(main)> "%.9f" % t
=> "999999999.999999046"
[37] pry(main)> "%.9f" % Time.now
=> "1390191794.227811098"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@tjwallace tjwallace Display nanosecond precision for Time and DateTime
This is a follow up to #331 and #416.

Linux creates Time objects with nanosecond precision so only displaying
microseconds can hide the differences between two objects.
f9ee8f9
@tjwallace

@myronmarston commits squashed into f9ee8f9

@myronmarston myronmarston merged commit be7c405 into rspec:master Jan 22, 2014

1 check passed

Details default The Travis CI build passed
@myronmarston
RSpec member

Thanks, @tjwallace!

@myronmarston myronmarston added a commit that referenced this pull request Jan 22, 2014
@myronmarston myronmarston Update changelog for #430.
[ci skip]
9b1fcc4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.