ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
* [ruby-core:98579] [Ruby master Feature#16470] Issue with nanoseconds in Time#inspect
       [not found] <redmine.issue-16470.20200101150406.13553@ruby-lang.org>
@ 2020-05-29 20:20 ` merch-redmine
  2020-06-18 11:24 ` [ruby-core:98867] " shyouhei
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 12+ messages in thread
From: merch-redmine @ 2020-05-29 20:20 UTC (permalink / raw
  To: ruby-core

Issue #16470 has been updated by jeremyevans0 (Jeremy Evans).

Backport deleted (2.5: UNKNOWN, 2.6: UNKNOWN)
ruby -v deleted (2.7)
Tracker changed from Bug to Feature

Even though this appears to be a bug, it's actually intentional behavior, introduced in commit:5208c431bef3240eb251f5da23723b324431a98e, and there are tests and specs for it.  So changing this behavior would be a feature request.

I think the behavior of displaying the rational is less useful, and the vast majority of Ruby programmers would want:

```ruby
Time.utc(2007, 11, 1, 15, 25, 0, 123456.789).inspect
# => "2007-11-01 15:25:00.123456789 UTC"
```

I've added a pull request to implement this: https://github.com/ruby/ruby/pull/3160

One disadvantage of the pull request's approach is that two Time objects that are not equal will have inspect output that is equal.   An alternative approach that wouldn't have that issue would be to rationalize all float usecs given as input, as @Eregon mentioned, but that could possibly have implications beyond inspect. With that approach, you would still end up with weird inspect output if providing a rational such as `8483885939586761/68719476736000000r` as usec input.

----------------------------------------
Feature #16470: Issue with nanoseconds in Time#inspect
https://bugs.ruby-lang.org/issues/16470#change-85890

* Author: andrykonchin (Andrew Konchin)
* Status: Open
* Priority: Normal
* Assignee: matz (Yukihiro Matsumoto)
----------------------------------------
Recently in Ruby 2.7 nanoseconds were added to a string representation produced by the `Time#inspect` method.

I encountered an issue when was working on new specs for the RubySpec project - nanoseconds are displaying like a Rational.

Let's illustrate it with example:

```ruby
t = Time.utc(2007, 11, 1, 15, 25, 0, 123456.789)
t.inspect # => "2007-11-01 15:25:00 8483885939586761/68719476736000000 UTC"
```

But nanoseconds are stored correctly:

```ruby
t.nsec # => 123456789
t.strftime("%N") # => "123456789"
```

So `123456789` is formatted as `8483885939586761/68719476736000000` which equals `0.12345678900000001`.

I assume it isn't expected behavior and will be fixed.



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [ruby-core:98867] [Ruby master Feature#16470] Issue with nanoseconds in Time#inspect
       [not found] <redmine.issue-16470.20200101150406.13553@ruby-lang.org>
  2020-05-29 20:20 ` [ruby-core:98579] [Ruby master Feature#16470] Issue with nanoseconds in Time#inspect merch-redmine
@ 2020-06-18 11:24 ` shyouhei
  2020-06-22 15:55 ` [ruby-core:98911] " merch-redmine
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 12+ messages in thread
From: shyouhei @ 2020-06-18 11:24 UTC (permalink / raw
  To: ruby-core

Issue #16470 has been updated by shyouhei (Shyouhei Urabe).


Note that the cryptic output does not happen for `Time.now.utc`.

```ruby
Time.now.utc.inspect # => "2020-06-18 11:12:44.354669166 UTC"
```

Nor when you pass `123456.789r` for `Time.utc`.

```ruby
Time.utc(2007, 11, 1, 15, 25, 0, 123456.789r) # => "2007-11-01 15:25:00.123456789 UTC"
```

So yes, as @eregon pointed out, this is not an issue of `Time#inspect`.  This is due to the OP is using `123456.789` for some reason not shown in the report.  `Time#inspect` is just trying to express as much as it can.

Is this usage (passing Float instances instead of Rationals) major in some area?  If so we might want to improve `Time.utc`'s API, not `Time#inspect`.

----------------------------------------
Feature #16470: Issue with nanoseconds in Time#inspect
https://bugs.ruby-lang.org/issues/16470#change-86232

* Author: andrykonchin (Andrew Konchin)
* Status: Open
* Priority: Normal
* Assignee: matz (Yukihiro Matsumoto)
----------------------------------------
Ruby 2.7 added nanosecond representation to the return value of `Time#inspect` method.

Nanosecond is displayed as `Rational` as in the following example:

```ruby
t = Time.utc(2007, 11, 1, 15, 25, 0, 123456.789)
t.inspect # => "2007-11-01 15:25:00 8483885939586761/68719476736000000 UTC"
```

The nanosecond value `8483885939586761/68719476736000000` can be expanded to `0.12345678900000001`. This is different from the stored nanosecond:

```ruby
t.nsec # => 123456789
t.strftime("%N") # => "123456789"
```

I assume it isn't expected, and will be fixed.



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [ruby-core:98911] [Ruby master Feature#16470] Issue with nanoseconds in Time#inspect
       [not found] <redmine.issue-16470.20200101150406.13553@ruby-lang.org>
  2020-05-29 20:20 ` [ruby-core:98579] [Ruby master Feature#16470] Issue with nanoseconds in Time#inspect merch-redmine
  2020-06-18 11:24 ` [ruby-core:98867] " shyouhei
@ 2020-06-22 15:55 ` merch-redmine
  2020-06-22 17:24 ` [ruby-core:98915] " eregontp
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 12+ messages in thread
From: merch-redmine @ 2020-06-22 15:55 UTC (permalink / raw
  To: ruby-core

Issue #16470 has been updated by jeremyevans0 (Jeremy Evans).


I've added an alternative approach, which uses Float#rationalize for all Float conversions in Time, except for Time.at (one test depends on `Time.at(float).to_f == float`): https://github.com/ruby/ruby/pull/3248

----------------------------------------
Feature #16470: Issue with nanoseconds in Time#inspect
https://bugs.ruby-lang.org/issues/16470#change-86292

* Author: andrykonchin (Andrew Konchin)
* Status: Open
* Priority: Normal
* Assignee: matz (Yukihiro Matsumoto)
----------------------------------------
Ruby 2.7 added nanosecond representation to the return value of `Time#inspect` method.

Nanosecond is displayed as `Rational` as in the following example:

```ruby
t = Time.utc(2007, 11, 1, 15, 25, 0, 123456.789)
t.inspect # => "2007-11-01 15:25:00 8483885939586761/68719476736000000 UTC"
```

The nanosecond value `8483885939586761/68719476736000000` can be expanded to `0.12345678900000001`. This is different from the stored nanosecond:

```ruby
t.nsec # => 123456789
t.strftime("%N") # => "123456789"
```

I assume it isn't expected, and will be fixed.



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [ruby-core:98915] [Ruby master Feature#16470] Issue with nanoseconds in Time#inspect
       [not found] <redmine.issue-16470.20200101150406.13553@ruby-lang.org>
                   ` (2 preceding siblings ...)
  2020-06-22 15:55 ` [ruby-core:98911] " merch-redmine
@ 2020-06-22 17:24 ` eregontp
  2020-06-22 18:05 ` [ruby-core:98916] " merch-redmine
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 12+ messages in thread
From: eregontp @ 2020-06-22 17:24 UTC (permalink / raw
  To: ruby-core

Issue #16470 has been updated by Eregon (Benoit Daloze).


One consideration here is performance.
For instance `Time.at(Float)` is quite slow, due to going through Rational, etc.
Could you measure the other methods you changed to see how they perform compared to before?

----------------------------------------
Feature #16470: Issue with nanoseconds in Time#inspect
https://bugs.ruby-lang.org/issues/16470#change-86295

* Author: andrykonchin (Andrew Konchin)
* Status: Open
* Priority: Normal
* Assignee: matz (Yukihiro Matsumoto)
----------------------------------------
Ruby 2.7 added nanosecond representation to the return value of `Time#inspect` method.

Nanosecond is displayed as `Rational` as in the following example:

```ruby
t = Time.utc(2007, 11, 1, 15, 25, 0, 123456.789)
t.inspect # => "2007-11-01 15:25:00 8483885939586761/68719476736000000 UTC"
```

The nanosecond value `8483885939586761/68719476736000000` can be expanded to `0.12345678900000001`. This is different from the stored nanosecond:

```ruby
t.nsec # => 123456789
t.strftime("%N") # => "123456789"
```

I assume it isn't expected, and will be fixed.



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [ruby-core:98916] [Ruby master Feature#16470] Issue with nanoseconds in Time#inspect
       [not found] <redmine.issue-16470.20200101150406.13553@ruby-lang.org>
                   ` (3 preceding siblings ...)
  2020-06-22 17:24 ` [ruby-core:98915] " eregontp
@ 2020-06-22 18:05 ` merch-redmine
  2020-06-23  2:58 ` [ruby-core:98918] " mame
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 12+ messages in thread
From: merch-redmine @ 2020-06-22 18:05 UTC (permalink / raw
  To: ruby-core

Issue #16470 has been updated by jeremyevans0 (Jeremy Evans).


Eregon (Benoit Daloze) wrote in #note-9:
> One consideration here is performance.
> For instance `Time.at(Float)` is quite slow, due to going through Rational, etc.
> Could you measure the other methods you changed to see how they perform compared to before?

Well, Time converts Float to Rational both with and without the patch (the values are passed through `num_exact`, which is where the conversion takes place). It is just a question of whether to use `to_r` or `rationalize` for the conversion (neither can be considered more accurate, since floating point numbers are inexact).  `rationalize` looks slightly faster, so this should slightly increase performance, not decrease it.

Here's an example with 2.7:

```
$ ruby -v
ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-openbsd]
$ ruby -r benchmark -ve 'eval "def a; #{"Time.utc(2007, 11, 1, 15, 25, 0, 123456.789.to_r);"*100000} end"; puts Benchmark.measure{a}'
  1.330000   0.030000   1.360000 (  1.426325)
$ ruby -r benchmark -ve 'eval "def a; #{"Time.utc(2007, 11, 1, 15, 25, 0, 123456.789.rationalize);"*100000} end"; puts Benchmark.measure{a}'
  1.230000   0.010000   1.240000 (  1.255797)
$ ruby -r benchmark -ve 'eval "def a; #{"Time.utc(2007, 11, 1, 15, 25, 0, 123456.789);"*100000} end"; puts Benchmark.measure{a}'
  1.350000   0.010000   1.360000 (  1.412875)
```

I tested with the patch and the test for the literal float was close to the `rationalize` value, not the `to_r` value. So the patch makes the code faster, not slower.

FWIW, it's significantly faster to pass a literal rational as opposed to converting a float to a rational or passing a literal float, both with and without the patch:

```
$ ruby -r benchmark -ve 'eval "def a; #{"Time.utc(2007, 11, 1, 15, 25, 0, 123456.789r);"*100000} end"; puts Benchmark.measure{a}'
  0.350000   0.030000   0.380000 (  0.496827)
```

----------------------------------------
Feature #16470: Issue with nanoseconds in Time#inspect
https://bugs.ruby-lang.org/issues/16470#change-86296

* Author: andrykonchin (Andrew Konchin)
* Status: Open
* Priority: Normal
* Assignee: matz (Yukihiro Matsumoto)
----------------------------------------
Ruby 2.7 added nanosecond representation to the return value of `Time#inspect` method.

Nanosecond is displayed as `Rational` as in the following example:

```ruby
t = Time.utc(2007, 11, 1, 15, 25, 0, 123456.789)
t.inspect # => "2007-11-01 15:25:00 8483885939586761/68719476736000000 UTC"
```

The nanosecond value `8483885939586761/68719476736000000` can be expanded to `0.12345678900000001`. This is different from the stored nanosecond:

```ruby
t.nsec # => 123456789
t.strftime("%N") # => "123456789"
```

I assume it isn't expected, and will be fixed.



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [ruby-core:98918] [Ruby master Feature#16470] Issue with nanoseconds in Time#inspect
       [not found] <redmine.issue-16470.20200101150406.13553@ruby-lang.org>
                   ` (4 preceding siblings ...)
  2020-06-22 18:05 ` [ruby-core:98916] " merch-redmine
@ 2020-06-23  2:58 ` mame
  2020-07-16  9:32 ` [ruby-core:99191] " mame
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 12+ messages in thread
From: mame @ 2020-06-23  2:58 UTC (permalink / raw
  To: ruby-core

Issue #16470 has been updated by mame (Yusuke Endoh).


Interesting, I can reproduce the performance difference:

```
$ time ./miniruby -e '100000.times { Time.utc(2007, 11, 1, 15, 25, 0, 123456.789.to_r) }'

real    0m0.633s
user    0m0.622s
sys     0m0.011s

$ time ./miniruby -e '100000.times { Time.utc(2007, 11, 1, 15, 25, 0, 123456.789.rationalize) }'

real    0m0.607s
user    0m0.587s
sys     0m0.020s
```

Note that `#to_r` is 10 times faster than `#rationalize`:

```
$ time ./miniruby -e '100000.times { 123456.789.to_r }'

real    0m0.059s
user    0m0.039s
sys     0m0.020s

$ time ./miniruby -e '100000.times { 123456.789.rationalize }'

real    0m0.598s
user    0m0.587s
sys     0m0.010s
```

I think that this is because `#to_r` produces relatively big denominator, which makes addition slower during `Time.utc` calculation.

(I have no opinion about the `Time.utc` issue itself.  Sorry.)

----------------------------------------
Feature #16470: Issue with nanoseconds in Time#inspect
https://bugs.ruby-lang.org/issues/16470#change-86297

* Author: andrykonchin (Andrew Konchin)
* Status: Open
* Priority: Normal
* Assignee: matz (Yukihiro Matsumoto)
----------------------------------------
Ruby 2.7 added nanosecond representation to the return value of `Time#inspect` method.

Nanosecond is displayed as `Rational` as in the following example:

```ruby
t = Time.utc(2007, 11, 1, 15, 25, 0, 123456.789)
t.inspect # => "2007-11-01 15:25:00 8483885939586761/68719476736000000 UTC"
```

The nanosecond value `8483885939586761/68719476736000000` can be expanded to `0.12345678900000001`. This is different from the stored nanosecond:

```ruby
t.nsec # => 123456789
t.strftime("%N") # => "123456789"
```

I assume it isn't expected, and will be fixed.



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [ruby-core:99191] [Ruby master Feature#16470] Issue with nanoseconds in Time#inspect
       [not found] <redmine.issue-16470.20200101150406.13553@ruby-lang.org>
                   ` (5 preceding siblings ...)
  2020-06-23  2:58 ` [ruby-core:98918] " mame
@ 2020-07-16  9:32 ` mame
  2020-07-16 17:25 ` [ruby-core:99195] " merch-redmine
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 12+ messages in thread
From: mame @ 2020-07-16  9:32 UTC (permalink / raw
  To: ruby-core

Issue #16470 has been updated by mame (Yusuke Endoh).


We need to understand the use case precisely.  Does OP want to pass a general Float value to `Time.utc`?  Or does he just want to specify nanosecond?

I think of no practical use case for the former (passing a general/calculated Float).  If we need to specify nanosecond, I don't think that Float is a good API for that.  `Time.utc(2007, 11, 1, 15, 25, 0, nanosecond: 123456789)` or something is better.


In addition, the following point is wrong.

> The nanosecond value 8483885939586761/68719476736000000 can be expanded to 0.12345678900000001.

A correct expansion is `0.123456789000000004307366907596588134765625`.  So, which is better?

```
t.inspect # => "2007-11-01 15:25:00 8483885939586761/68719476736000000 UTC"
t.inspect # => "2007-11-01 15:25:00.123456789000000004307366907596588134765625 UTC"
```

Personally, I prefer the latter to the former because decimal is much easier to understand.

However, I'm afraid if the expansion might be very long. Truncation is a possible, of course. But, it will break the original reason why the fraction part is added in Time#inspect (#15958):

> But recently we encounters some troubles the comparison of Time objects whose frac parts are different.

So, naive truncation may bring the same troubles again. I guess nanosecond (nine digits after the decimal point) would be enough in many use cases, but I'm not 100% sure.

----------------------------------------
Feature #16470: Issue with nanoseconds in Time#inspect
https://bugs.ruby-lang.org/issues/16470#change-86572

* Author: andrykonchin (Andrew Konchin)
* Status: Open
* Priority: Normal
* Assignee: matz (Yukihiro Matsumoto)
----------------------------------------
Ruby 2.7 added nanosecond representation to the return value of `Time#inspect` method.

Nanosecond is displayed as `Rational` as in the following example:

```ruby
t = Time.utc(2007, 11, 1, 15, 25, 0, 123456.789)
t.inspect # => "2007-11-01 15:25:00 8483885939586761/68719476736000000 UTC"
```

The nanosecond value `8483885939586761/68719476736000000` can be expanded to `0.12345678900000001`. This is different from the stored nanosecond:

```ruby
t.nsec # => 123456789
t.strftime("%N") # => "123456789"
```

I assume it isn't expected, and will be fixed.



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [ruby-core:99195] [Ruby master Feature#16470] Issue with nanoseconds in Time#inspect
       [not found] <redmine.issue-16470.20200101150406.13553@ruby-lang.org>
                   ` (6 preceding siblings ...)
  2020-07-16  9:32 ` [ruby-core:99191] " mame
@ 2020-07-16 17:25 ` merch-redmine
  2020-07-16 17:47 ` [ruby-core:99196] " eregontp
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 12+ messages in thread
From: merch-redmine @ 2020-07-16 17:25 UTC (permalink / raw
  To: ruby-core

Issue #16470 has been updated by jeremyevans0 (Jeremy Evans).


mame (Yusuke Endoh) wrote in #note-12:
> I guess nanosecond (nine digits after the decimal point) would be enough in many use cases, but I'm not 100% sure.

I don't think support for fractional nanoseconds is important.  Does anyone have a use case for fractional nanoseconds?  If not, I think it would be best to change Time to just store nanoseconds as integer instead of a rational.  However, that's definitely a more involved change.

----------------------------------------
Feature #16470: Issue with nanoseconds in Time#inspect
https://bugs.ruby-lang.org/issues/16470#change-86575

* Author: andrykonchin (Andrew Konchin)
* Status: Open
* Priority: Normal
* Assignee: matz (Yukihiro Matsumoto)
----------------------------------------
Ruby 2.7 added nanosecond representation to the return value of `Time#inspect` method.

Nanosecond is displayed as `Rational` as in the following example:

```ruby
t = Time.utc(2007, 11, 1, 15, 25, 0, 123456.789)
t.inspect # => "2007-11-01 15:25:00 8483885939586761/68719476736000000 UTC"
```

The nanosecond value `8483885939586761/68719476736000000` can be expanded to `0.12345678900000001`. This is different from the stored nanosecond:

```ruby
t.nsec # => 123456789
t.strftime("%N") # => "123456789"
```

I assume it isn't expected, and will be fixed.



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [ruby-core:99196] [Ruby master Feature#16470] Issue with nanoseconds in Time#inspect
       [not found] <redmine.issue-16470.20200101150406.13553@ruby-lang.org>
                   ` (7 preceding siblings ...)
  2020-07-16 17:25 ` [ruby-core:99195] " merch-redmine
@ 2020-07-16 17:47 ` eregontp
  2020-07-20  3:15 ` [ruby-core:99229] " akr
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 12+ messages in thread
From: eregontp @ 2020-07-16 17:47 UTC (permalink / raw
  To: ruby-core

Issue #16470 has been updated by Eregon (Benoit Daloze).


I also don't see much use for fractional nanoseconds.
`clock_gettime()` never has higher resolution than nanoseconds.

In fact both JRuby and TruffleRuby always round to an integer number of nanonseconds, because `java.time` supports nanoseconds but not more fine-grained than that (since nothing could provide such precision).

----------------------------------------
Feature #16470: Issue with nanoseconds in Time#inspect
https://bugs.ruby-lang.org/issues/16470#change-86576

* Author: andrykonchin (Andrew Konchin)
* Status: Open
* Priority: Normal
* Assignee: matz (Yukihiro Matsumoto)
----------------------------------------
Ruby 2.7 added nanosecond representation to the return value of `Time#inspect` method.

Nanosecond is displayed as `Rational` as in the following example:

```ruby
t = Time.utc(2007, 11, 1, 15, 25, 0, 123456.789)
t.inspect # => "2007-11-01 15:25:00 8483885939586761/68719476736000000 UTC"
```

The nanosecond value `8483885939586761/68719476736000000` can be expanded to `0.12345678900000001`. This is different from the stored nanosecond:

```ruby
t.nsec # => 123456789
t.strftime("%N") # => "123456789"
```

I assume it isn't expected, and will be fixed.



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [ruby-core:99229] [Ruby master Feature#16470] Issue with nanoseconds in Time#inspect
       [not found] <redmine.issue-16470.20200101150406.13553@ruby-lang.org>
                   ` (8 preceding siblings ...)
  2020-07-16 17:47 ` [ruby-core:99196] " eregontp
@ 2020-07-20  3:15 ` akr
  2020-07-20  3:33 ` [ruby-core:99230] " akr
  2020-07-20 19:16 ` [ruby-core:99240] " merch-redmine
  11 siblings, 0 replies; 12+ messages in thread
From: akr @ 2020-07-20  3:15 UTC (permalink / raw
  To: ruby-core

Issue #16470 has been updated by akr (Akira Tanaka).


There are several examples time needs more than nanoseconds.

* SQLite supports arbitrary number of digits in fractional seconds
  https://www.sqlite.org/lang_datefunc.html
* POSIX pax format supports arbitrary number of digits in fractional seconds
  http://pubs.opengroup.org/onlinepubs/007904875/utilities/pax.html#tag_04_100_13_05
* EXIF supports arbitrary number of digits in fractional seconds
  http://www.exif.org/Exif2-1.PDF
* NTPv4's 128-bit date format has 64-bit fraction field : 2**(-64) second
  https://tools.ietf.org/html/rfc5905#section-6
* FreeBSD has struct bintime which can represent 2**(-64) second
  https://svnweb.freebsd.org/base/head/sys/sys/time.h?view=markup&pathrev=363193#l55
  It is visible from userland for datagram timestamp
  https://www.freebsd.org/cgi/man.cgi?query=setsockopt
  Ruby supports it as converting bintime to Time object
* DB2 supports fractional seconds up to 12 digits in timestamp (12 digits represents picosecond)
  https://www.ibm.com/support/knowledgecenter/SSEPGG_9.7.0/com.ibm.db2.luw.sql.ref.doc/doc/r0008474.html


 

----------------------------------------
Feature #16470: Issue with nanoseconds in Time#inspect
https://bugs.ruby-lang.org/issues/16470#change-86613

* Author: andrykonchin (Andrew Konchin)
* Status: Open
* Priority: Normal
* Assignee: matz (Yukihiro Matsumoto)
----------------------------------------
Ruby 2.7 added nanosecond representation to the return value of `Time#inspect` method.

Nanosecond is displayed as `Rational` as in the following example:

```ruby
t = Time.utc(2007, 11, 1, 15, 25, 0, 123456.789)
t.inspect # => "2007-11-01 15:25:00 8483885939586761/68719476736000000 UTC"
```

The nanosecond value `8483885939586761/68719476736000000` can be expanded to `0.12345678900000001`. This is different from the stored nanosecond:

```ruby
t.nsec # => 123456789
t.strftime("%N") # => "123456789"
```

I assume it isn't expected, and will be fixed.



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [ruby-core:99230] [Ruby master Feature#16470] Issue with nanoseconds in Time#inspect
       [not found] <redmine.issue-16470.20200101150406.13553@ruby-lang.org>
                   ` (9 preceding siblings ...)
  2020-07-20  3:15 ` [ruby-core:99229] " akr
@ 2020-07-20  3:33 ` akr
  2020-07-20 19:16 ` [ruby-core:99240] " merch-redmine
  11 siblings, 0 replies; 12+ messages in thread
From: akr @ 2020-07-20  3:33 UTC (permalink / raw
  To: ruby-core

Issue #16470 has been updated by akr (Akira Tanaka).

Status changed from Open to Feedback

As others already pointed, 
the original description of this issue misunderstand the actual Ruby behavior.

`Time.utc(2007, 11, 1, 15, 25, 0, 123456.789)` creates a Time object which has 
0.123456789000000004307366907596588134765625 as a fractional second
because the exact value of float 123456.789 is
123456.789000000004307366907596588134765625.

I think the description "This is different from the stored nanosecond: ..." is based on misunderstanding of actual Ruby behavior.

So, it is difficult to determine actual problem.
We'd like to hear.



----------------------------------------
Feature #16470: Issue with nanoseconds in Time#inspect
https://bugs.ruby-lang.org/issues/16470#change-86614

* Author: andrykonchin (Andrew Konchin)
* Status: Feedback
* Priority: Normal
* Assignee: matz (Yukihiro Matsumoto)
----------------------------------------
Ruby 2.7 added nanosecond representation to the return value of `Time#inspect` method.

Nanosecond is displayed as `Rational` as in the following example:

```ruby
t = Time.utc(2007, 11, 1, 15, 25, 0, 123456.789)
t.inspect # => "2007-11-01 15:25:00 8483885939586761/68719476736000000 UTC"
```

The nanosecond value `8483885939586761/68719476736000000` can be expanded to `0.12345678900000001`. This is different from the stored nanosecond:

```ruby
t.nsec # => 123456789
t.strftime("%N") # => "123456789"
```

I assume it isn't expected, and will be fixed.



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [ruby-core:99240] [Ruby master Feature#16470] Issue with nanoseconds in Time#inspect
       [not found] <redmine.issue-16470.20200101150406.13553@ruby-lang.org>
                   ` (10 preceding siblings ...)
  2020-07-20  3:33 ` [ruby-core:99230] " akr
@ 2020-07-20 19:16 ` merch-redmine
  11 siblings, 0 replies; 12+ messages in thread
From: merch-redmine @ 2020-07-20 19:16 UTC (permalink / raw
  To: ruby-core

Issue #16470 has been updated by jeremyevans0 (Jeremy Evans).


akr (Akira Tanaka) wrote in #note-16:
> There are several examples time needs more than nanoseconds.
> 
> * SQLite supports arbitrary number of digits in fractional seconds
>   https://www.sqlite.org/lang_datefunc.html

SQLite ignores values after the millisecond when converting:

```
sqlite> SELECT CAST(strftime('%f', '2020-10-20 11:12:13.1237') AS NUMERIC);
13.124
```

> * POSIX pax format supports arbitrary number of digits in fractional seconds
>   http://pubs.opengroup.org/onlinepubs/007904875/utilities/pax.html#tag_04_100_13_05

This is a file archive format.  How many filesystems have greater than nanosecond resolution?

> * EXIF supports arbitrary number of digits in fractional seconds
>   http://www.exif.org/Exif2-1.PDF

Similarly, what camera supports greater than nanosecond resolution?

> * NTPv4's 128-bit date format has 64-bit fraction field : 2**(-64) second
>   https://tools.ietf.org/html/rfc5905#section-6
> * FreeBSD has struct bintime which can represent 2**(-64) second
>   https://svnweb.freebsd.org/base/head/sys/sys/time.h?view=markup&pathrev=363193#l55
>   It is visible from userland for datagram timestamp
>   https://www.freebsd.org/cgi/man.cgi?query=setsockopt
>   Ruby supports it as converting bintime to Time object
> * DB2 supports fractional seconds up to 12 digits in timestamp (12 digits represents picosecond)
>   https://www.ibm.com/support/knowledgecenter/SSEPGG_9.7.0/com.ibm.db2.luw.sql.ref.doc/doc/r0008474.html

These seem to be better reasons to support sub-nanosecond resolution.  I think either storing picoseconds or storing sec fraction as 64-bit integer are better approaches than storing a rational.  However, either change would be very invasive, and it seems unlikely to be worth the effort.

As rational is used internally, it seems reasonably for inspect output to include rational.  If a user wants to specific nanosecond, they should provide a rational instead of a float.  So I think this feature request can be closed.

Note that sub-nanosecond resolution should be considered Ruby-implementation-specific behavior, since JRuby and TruffleRuby support nanosecond, and mruby supports microsecond.

----------------------------------------
Feature #16470: Issue with nanoseconds in Time#inspect
https://bugs.ruby-lang.org/issues/16470#change-86624

* Author: andrykonchin (Andrew Konchin)
* Status: Feedback
* Priority: Normal
* Assignee: matz (Yukihiro Matsumoto)
----------------------------------------
Ruby 2.7 added nanosecond representation to the return value of `Time#inspect` method.

Nanosecond is displayed as `Rational` as in the following example:

```ruby
t = Time.utc(2007, 11, 1, 15, 25, 0, 123456.789)
t.inspect # => "2007-11-01 15:25:00 8483885939586761/68719476736000000 UTC"
```

The nanosecond value `8483885939586761/68719476736000000` can be expanded to `0.12345678900000001`. This is different from the stored nanosecond:

```ruby
t.nsec # => 123456789
t.strftime("%N") # => "123456789"
```

I assume it isn't expected, and will be fixed.



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2020-07-20 19:17 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <redmine.issue-16470.20200101150406.13553@ruby-lang.org>
2020-05-29 20:20 ` [ruby-core:98579] [Ruby master Feature#16470] Issue with nanoseconds in Time#inspect merch-redmine
2020-06-18 11:24 ` [ruby-core:98867] " shyouhei
2020-06-22 15:55 ` [ruby-core:98911] " merch-redmine
2020-06-22 17:24 ` [ruby-core:98915] " eregontp
2020-06-22 18:05 ` [ruby-core:98916] " merch-redmine
2020-06-23  2:58 ` [ruby-core:98918] " mame
2020-07-16  9:32 ` [ruby-core:99191] " mame
2020-07-16 17:25 ` [ruby-core:99195] " merch-redmine
2020-07-16 17:47 ` [ruby-core:99196] " eregontp
2020-07-20  3:15 ` [ruby-core:99229] " akr
2020-07-20  3:33 ` [ruby-core:99230] " akr
2020-07-20 19:16 ` [ruby-core:99240] " merch-redmine

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).