Project

General

Profile

Feature #15879

Proposal: Time#to_i accepts :unit keyword

Added by joker1007 (Tomohiro Hashidate) 3 months ago. Updated 24 days ago.

Status:
Open
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:92857]

Description

I often need Unix time as microseconds or nanoseconds to serialize for other language environments.
For example, Java uses milliseconds(nanoseconds) basically.

In such a situation, current Ruby code is like below.

{
  event_id: id,
  name: name,
  tracked_at: (tracked_at.to_f * 1000).round,
  tracked_at_micro: (tracked_at * 1000000 + tracked_at.usec)
}

But this example is noisy. And it is easy to make a mistake.
I want to write like below.

{
  event_id: id,
  name: name,
  tracked_at: tracked_at.to_i(unit: :milli),
  tracked_at_micro: tracked_at.to_i(unit: :micro)
}

# or 

{
  event_id: id,
  name: name,
  tracked_at: tracked_at.as_msec,
  tracked_at_micro: tracked_at.as_usec
}

History

Updated by sawa (Tsuyoshi Sawada) 3 months ago

By analogy from Time#round, which takes as an argument an integer representing the precision in decimal places, and from String#to_i, which takes an integer, I think that passing an integer representing the number of decimal places would fit better. Something like this:

{
  event_id: id,
  name: name,
  tracked_at: tracked_at.to_i(3),
  tracked_at_micro: tracked_at.to_i(6)
}

Default would be 0.

Updated by sawa (Tsuyoshi Sawada) 3 months ago

With Float#to_i, the decimal part is truncated, not rounded:

123.7.to_i # => 123
123.7.round # => 124

In contrast to this, your proposal with Time#to_i seems to return rounded results even though the method name is to_i. I think this is confusing. Is this your intention?

Updated by phluid61 (Matthew Kerwin) 3 months ago

You can also use Time#to_r:

{
  event_id: id,
  name: name,
  tracked_at: (tracked_at.to_r * 1_000).to_i,
  tracked_at_micro: (tracked_at.to_r * 1_000_000).to_i
}

At least it's always the same multiply-and-truncate operation.

Updated by shevegen (Robert A. Heiler) 3 months ago

I agree with sawa's comment - this is a bit surprising, at the least to me as well. It would
be better to re-use the same idioms, so that ruby users are not surprised by behaviour, if
it can be avoided.

But I think this is only one part of the suggestion; the other is about a simpler API,
at the least that is how I understood it in the context of the example here.

I have no particular pro/con opinion per se on the proposed functionality; I have had
to deal with time stamps in audio/video code too, so I understand the requirement to
work with milliseconds, including making this data available to other languages or in
e. g. json or yaml - but in general, ruby may have to be a bit conservative in what is
exposed to other "downstream" ruby users API-wise. For example, some time ago :exception
added to some methods, which I think was a good/useful change, at the least for those
ruby users who may require the functionality; ruby may have to be somewhat conservative
in what may be exposed API-wise. It may be difficult to memorize 1000 different
symbols. :D

Perhaps in the long run we could have something similar to require 'English', defining some
useful "decorator" symbols, such as in the example given above, via unit: :milli, and then
"decorating" methods with this, when they meaningfully use time-related code - but I think
that this may require some more discussion in general. Matz also made comments about this
in the past in another context; I don't fully recall the idea, but I think it was somewhat
related to "interfaces" to methods or method signatures or something like that.

I wanted to write a bit more, e. g. giving the example of ruby-gtk using more symbols,
such as :bold rather than harder-to-remember Pango::FontDescription::BOLD, or something
like that, but I think I already wrote too much, so I will stop here.

Updated by joker1007 (Tomohiro Hashidate) 3 months ago

In contrast to this, your proposal with Time#to_i seems to return rounded results even though the method name is to_i. I think this is confusing. Is this your intention?

It is not important whether the result is rounded or truncated. I'm sorry, this examples is not good.
The main problem that I must write 1_000_000 whenever I need time as microseconds. And so, Such a situaion is often.

Updated by ko1 (Koichi Sasada) 24 days ago

joker-san, if you are interest about this ticket yet, could you file on our dev-meeting agenda?
https://bugs.ruby-lang.org/issues/15996

Thanks.

Also available in: Atom PDF