除非使用UTC,否则DateTime不允许添加毫秒

时间:2019-02-01 21:37:36

标签: ruby-on-rails ruby datetime ruby-on-rails-5

我想在DateTime对象中添加毫秒数,发现它被忽略了,仅应用了整数(当使用超过1.0的值时)。

如您所见,使用Time对象或在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" 会产生正确的结果:

.utc

为什么?为什么标准的DateTime忽略毫秒? {{1}}调用会做什么,突然使对象表现出所需的行为?

1 个答案:

答案 0 :(得分:2)

一个DateTime和在其上调用.utc所得到的是两个不同的对象,因此,当您向每个对象添加内容时,这些对象中的每个对象都可以按照自己的意愿强迫另一个对象。

DateTime是一个DateTime对象,而至少在DateTime对象上调用.utc会返回一个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