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

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

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

 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)> 

最近更新 :我在一个或两个星期前在HA服务上工作的基础上,对这个主题中的顶级解决scheme进行了基准testing,并且惊奇地发现Time.at(..)优于DateTime.strptime(..) (update:added more benchmarkmarks )。

 # ~ % 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显示一个返回值,并要求秒数为一个string,并输出一个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方法打印截然不同的string。 虽然,如果我们看看string,我们可以看到它们确实是同一时间,只是印在不同的时区。

方法论证澄清

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

 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 

****编辑不完全和完全不正确的各方面****

一个命令将date时间转换为Unix格式,然后转换为string

  DateTime.strptime(Time.now.utc.to_i.to_s,'%s').strftime("%d %m %y") Time.now.utc.to_i #Converts time from Unix format DateTime.strptime(Time.now.utc.to_i.to_s,'%s') #Converts date and time from unix format to DateTime 

最后strftime用来格式化date

例:

  irb(main):034:0> DateTime.strptime("1410321600",'%s').strftime("%d %m %y") "10 09 14" 

这会告诉你从执行代码的那一刻起的date秒数。

 time = Time.new + 1000000000 #date in 1 billion seconds 

看跌期权(时间)

根据当前时间我回答的问题打印047-05-14 05:16:16 +0000 (未来10亿秒)

或者如果要从特定时间计数十亿秒, Time.mktime(year, month,date,hours,minutes)

 time = Time.mktime(1987,8,18,6,45) + 1000000000 

放(“我会是10亿秒老:”+时间)

如果您只需要date,则可以执行Date.strptime(invoice.date.to_s, '%s') ,其中Date.strptime(invoice.date.to_s, '%s')Fixnum的forms出现,然后转换为String