DateTime не позволяет добавлять миллисекунды, если не указано UTC - PullRequest
0 голосов
/ 02 февраля 2019

Я хочу добавить миллисекунды к объекту DateTime и обнаружил, что он игнорируется, применяется только целое число (при использовании значений более 1,0).

Как вы можете видеть, используя объект Time или вызов.utc в DateTime дает правильный результат:

utc_datetime = (DateTime.new(2018, 8, 8, 10, 24, 45.856).utc + 0.5.seconds).to_s(:ms_hr)
# => "2018-08-08 10:24:46.356"

non_utc_datetime = (DateTime.new(2018, 8, 8, 10, 24, 45.856) + 0.5.seconds).to_s(:ms_hr)
#=> "2018-08-08 10:24:46.856"

time = (Time.new(2018, 8, 8, 10, 24, 45.856) + 0.5.seconds).to_s(:ms_hr)
#=> "2018-08-08 10:24:46.356"

Почему?Почему стандартный DateTime игнорирует миллисекунды?Что делает вызов .utc, который внезапно заставляет объект вести себя как нужно?

1 Ответ

0 голосов
/ 02 февраля 2019

A DateTime и то, что вы получаете, вызывая .utc для него, - это два разных объекта, поэтому, когда вы добавляете что-то к каждому, каждый из этих объектов может привести другой объект к своему усмотрению.

DateTime является объектом DateTime, в то время как в rails, по крайней мере, вызов .utc для объекта DateTime вернет объект Time.

В случае DateTime это выглядит так, как будто ожидается, что значение после + будет в днях, в то время как Time ожидает, что значение будет в секундах.

Например,

(DateTime.new(2018, 8, 8, 10, 24, 45.856) )
2.4.1 :050 > (DateTime.new(2018, 8, 8, 10, 24, 45.856) )
 => #<DateTime: 2018-08-08T10:24:45+00:00 ((2458339j,37485s,856000000n),+0s,2299161j)> 

# add 1 day
2.4.1 :051 > (DateTime.new(2018, 8, 8, 10, 24, 45.856) + 1 )
 => #<DateTime: 2018-08-09T10:24:45+00:00 ((2458340j,37485s,856000000n),+0s,2299161j)> 

# add 100ms
2.4.1 :052 > (DateTime.new(2018, 8, 8, 10, 24, 45.856) + 0.1/60.0/60.0/24.0)
 => #<DateTime: 2018-08-08T10:24:45+00:00 ((2458339j,37485s,956000000n),+0s,2299161j)> 

# add 1s
2.4.1 :053 > (DateTime.new(2018, 8, 8, 10, 24, 45.856) + 1.0/60.0/60.0/24.0)
 => #<DateTime: 2018-08-08T10:24:46+00:00 ((2458339j,37486s,856000000n),+0s,2299161j)> 

Другой пример, демонстрирующий происходящее:

2.4.1 :081 > t = Time.now
 => 2019-02-02 09:20:23 -0500 

# adding 1 to a time object adds a second
2.4.1 :082 > (t + 1).to_i - t.to_i
 => 1 

2.4.1 :083 > d = DateTime.now
 => #<DateTime: 2019-02-02T09:20:58-05:00 ((2458517j,51658s,883341147n),-18000s,2299161j)> 

# adding 1 to a DateTime object add 60*60*24 = 86400 seconds, ie 1 day
2.4.1 :085 > (d + 1).to_time.to_i - d.to_time.to_i
 => 86400 
...