Home > Blockchain >  Convert milliseconds to Time without losing precision
Convert milliseconds to Time without losing precision

Time:02-12

Time.current gives me precision beyond seconds:

> Time.current
Fri, 11 Feb 2022 23:00:18.253185000 UTC  00:00
> Time.current.to_f
1644620430.942064

But Time.at loses the precision :(

> Time.at(1644620430.942064).utc
2022-02-11 23:00:30 UTC

The whole .942064 got truncated. This is messing with some tests that compare dates, because timestamps seem to save with the milliseconds, but I don't know how to create a Time that includes milliseconds

How can I cast a variable of milliseconds into a Time?

CodePudding user response:

As I understand you need nanoseconds precision

Time::at has such form

time = Time.current
# => Fri, 11 Feb 2022 23:36:25.983398537 UTC  00:00

float_time = time.to_f
# => 1644622585.9833987

secs = float_time.floor
# => 1644622585

nsecs = time.nsec
# => 983398537

Time.at(secs, nsecs, :nsec).utc
# => 2022-02-11 23:36:25.983398537 UTC

You can choose precision using one of these keys:

  • :msec is the number of milliseconds (Integer, Float, or Rational) in the range 0..1000

  • :usec is the number of microseconds (Integer, Float, or Rational) in the range 0..1000000

  • :nsec key is the number of nanoseconds (Integer, Float, or Rational) in the range 0..1000000000

You can also just call utc on Time.current

time = Time.current
# => Fri, 11 Feb 2022 23:36:25.983398537 UTC  00:00

time.utc
# => 2022-02-11 23:36:25.983398537 UTC

CodePudding user response:

I think you're just seeing a formatting problem. Consider:

Time.at(1644620430.942064).strftime('%Y-%m-%dT%H:%M:%S.%N')
# 2022-02-11T15:00:30.942064046

However, if you call to_s:

Time.at(1644620430.942064).to_s
# "2022-02-11 15:00:30 -0800" 
Time.at(1644620430.942064).utc.to_s
# "2022-02-11 23:00:30 UTC" 

you only get results with one second resolution.

The full precision time is there but you need to be careful to ask for it when you format your time.

  • Related