如何将unix时间戳(自epoch以来的秒数)转换为Ruby DateTime?

如何将Unix时间戳记(自epoch以来的秒数)转换为Ruby DateTime?


DateTime.strptime可以处理自纪元以来的秒数。 该数字必须转换为字符串:

require 'date'
DateTime.strptime("1318996912",'%s')

对不起,突然失败的短暂时刻。 这是真正的答案。

require 'date'

Time.at(seconds_since_epoch_integer).to_datetime

简单的例子 (这考虑到了当前的系统时区):

$ date +%s
1318996912

$ irb

ruby-1.9.2-p180 :001 > require 'date'
 => true 

ruby-1.9.2-p180 :002 > Time.at(1318996912).to_datetime
 => #<DateTime: 2011-10-18T23:01:52-05:00 (13261609807/5400,-5/24,2299161)> 

进一步更新 (对于UTC):

ruby-1.9.2-p180 :003 > Time.at(1318996912).utc.to_datetime
 => #<DateTime: 2011-10-19T04:01:52+00:00 (13261609807/5400,0/1,2299161)>

最近更新 :我在一周或两周前从事高可用性服务的同时,在本主题中测试了顶级解决方案,并惊奇地发现Time.at(..)优于DateTime.strptime(..) (更新:增加了更多基准测试)。

# ~ % ruby -v
#  => ruby 2.1.5p273 (2014-11-13 revision 48405) [x86_64-darwin13.0]

irb(main):038:0> Benchmark.measure do
irb(main):039:1*   ["1318996912", "1318496912"].each do |s|
irb(main):040:2*     DateTime.strptime(s, '%s')
irb(main):041:2>   end
irb(main):042:1> end

=> #<Benchmark ... @real=2.9e-05 ... @total=0.0>

irb(main):044:0> Benchmark.measure do
irb(main):045:1>   [1318996912, 1318496912].each do |i|
irb(main):046:2>     DateTime.strptime(i.to_s, '%s')
irb(main):047:2>   end
irb(main):048:1> end

=> #<Benchmark ... @real=2.0e-05 ... @total=0.0>

irb(main):050:0* Benchmark.measure do
irb(main):051:1*   ["1318996912", "1318496912"].each do |s|
irb(main):052:2*     Time.at(s.to_i).to_datetime
irb(main):053:2>   end
irb(main):054:1> end

=> #<Benchmark ... @real=1.5e-05 ... @total=0.0>

irb(main):056:0* Benchmark.measure do
irb(main):057:1*   [1318996912, 1318496912].each do |i|
irb(main):058:2*     Time.at(i).to_datetime
irb(main):059:2>   end
irb(main):060:1> end

=> #<Benchmark ... @real=2.0e-05 ... @total=0.0>

时区处理

我只想澄清一下,尽管这已经有所评论,所以未来的人们不会错过这个非常重要的区别。

DateTime.strptime("1318996912",'%s') # => Wed, 19 Oct 2011 04:01:52 +0000

以UTC显示一个返回值,并要求秒数为一个字符串并输出一个UTC时间对象,而

Time.at(1318996912) # => 2011-10-19 00:01:52 -0400

在LOCAL时区中显示返回值,通常需要FixNum参数,但即使显示不是UTC,Time对象本身仍然是UTC。

所以,即使我将同一个整数传递给两个方法,由于类' #to_s方法的工作原理,我看起来有两个不同的结果。 但是,@Eero不得不提醒我两次:

Time.at(1318996912) == DateTime.strptime("1318996912",'%s') # => true

两个返回值之间的等式比较仍然返回true。 同样,这是因为这些值基本相同(尽管不同的类, #==方法会为您处理此问题),但#to_s方法会打印截然不同的字符串。 虽然,如果我们看看这些琴弦,我们可以看到他们确实是同一时间,只是印在不同的时区。

方法论证说明

文档也会说“如果给出数字参数,结果是在当地时间。” 这是有道理的,但对我来说有点困惑,因为他们没有给出文档中任何非整数参数的例子。 所以,对于一些非整数参数的例子:

Time.at("1318996912")
TypeError: can't convert String into an exact number

你不能使用String参数,但是你可以在Time.at使用Time参数,它将返回参数时区的结果:

Time.at(Time.new(2007,11,1,15,25,0, "+09:00"))
=> 2007-11-01 15:25:00 +0900

****编辑不完全和完全不正确的方式****

链接地址: http://www.djcxy.com/p/4269.html

上一篇: How to convert a unix timestamp (seconds since epoch) to Ruby DateTime?

下一篇: Convert a Unix timestamp to time in JavaScript