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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7816365/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-06 04:24:00  来源:igfitidea点击:

How to convert a unix timestamp (seconds since epoch) to Ruby DateTime?

rubydatetimetimestamp

提问by Tronathan

How do you convert a Unix timestamp (seconds since epoch) to Ruby DateTime?

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

采纳答案by steenslag

DateTime.strptimecan handle seconds since epoch. The number must be converted to a string:

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

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

回答by Adam Eberlin

Sorry, brief moment of synapse failure. Here's the real answer.

抱歉,短暂的突触故障。这是真正的答案。

require 'date'

Time.at(seconds_since_epoch_integer).to_datetime

Brief example(this takes into account the current system timezone):

简要示例(这考虑了当前系统时区):

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

Further update(for UTC):

进一步更新(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)>

Recent Update: I benchmarked the top solutions in this thread while working on a HA service a week or two ago, and was surprised to find that Time.at(..)outperforms DateTime.strptime(..)(update: added more benchmarks).

最近的更新:我在一两周前在 HA 服务上工作时对这个线程中的顶级解决方案进行了基准测试,并惊讶地发现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>

回答by WattsInABox

Time Zone Handling

时区处理

I just want to clarify, even though this has been commented so future people don't miss this very important distinction.

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

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

displays a return value in UTC and requires the seconds to be a String and outputs a UTC Time object, whereas

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

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

displays a return value in the LOCAL time zone, normally requires a FixNum argument, but the Time object itself is still in UTC even though the display is not.

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

So even though I passed the same integer to both methods, I seemingly two different results because of how the class' #to_smethod works. However, as @Eero had to remind me twice of:

因此,即使我将相同的整数传递给这两种方法,由于类#to_s方法的工作方式,我似乎得到了两种不同的结果。但是,正如@Eero 不得不两次提醒我:

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

An equality comparison between the two return values still returns true. Again, this is because the values are basically the same (although different classes, the #==method takes care of this for you), but the #to_smethod prints drastically different strings. Although, if we look at the strings, we can see they are indeed the same time, just printed in different time zones.

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

Method Argument Clarification

方法论点澄清

The docs also say "If a numeric argument is given, the result is in local time." which makes sense, but was a little confusing to me because they don't give any examples of non-integer arguments in the docs. So, for some non-integer argument examples:

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

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

you can't use a String argument, but you can use a Time argument into Time.atand it will return the result in the time zone of the argument:

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

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

Benchmarks

基准

After a discussion with @AdamEberlin on his answer, I decided to publish slightly changed benchmarks to make everything as equal as possible. Also, I never want to have to build these again so this is as good a place as any to save them.

在与@AdamEberlin 讨论他的回答后,我决定发布稍微改变的基准,以使一切尽可能平等。此外,我永远不想再次建造这些,所以这是一个保存它们的好地方。

Time.at(int).to_datetime ~ 2.8x faster

Time.at(int).to_datetime ~ 2.8x 快

09:10:58-watsw018:~$ ruby -v
ruby 2.3.7p456 (2018-03-28 revision 63024) [universal.x86_64-darwin18]
09:11:00-watsw018:~$ irb
irb(main):001:0> require 'benchmark'
=> true
irb(main):002:0> require 'date'
=> true
irb(main):003:0>
irb(main):004:0* format = '%s'
=> "%s"
irb(main):005:0> times = ['1318996912', '1318496913']
=> ["1318996912", "1318496913"]
irb(main):006:0> int_times = times.map(&:to_i)
=> [1318996912, 1318496913]
irb(main):007:0>
irb(main):008:0* datetime_from_strptime = DateTime.strptime(times.first, format)
=> #<DateTime: 2011-10-19T04:01:52+00:00 ((2455854j,14512s,0n),+0s,2299161j)>
irb(main):009:0> datetime_from_time = Time.at(int_times.first).to_datetime
=> #<DateTime: 2011-10-19T00:01:52-04:00 ((2455854j,14512s,0n),-14400s,2299161j)>
irb(main):010:0>
irb(main):011:0* datetime_from_strptime === datetime_from_time
=> true
irb(main):012:0>
irb(main):013:0* Benchmark.measure do
irb(main):014:1*   100_000.times {
irb(main):015:2*     times.each do |i|
irb(main):016:3*       DateTime.strptime(i, format)
irb(main):017:3>     end
irb(main):018:2>   }
irb(main):019:1> end
=> #<Benchmark::Tms:0x00007fbdc18f0d28 @label="", @real=0.8680500000045868, @cstime=0.0, @cutime=0.0, @stime=0.009999999999999998, @utime=0.86, @total=0.87>
irb(main):020:0>
irb(main):021:0* Benchmark.measure do
irb(main):022:1*   100_000.times {
irb(main):023:2*     int_times.each do |i|
irb(main):024:3*       Time.at(i).to_datetime
irb(main):025:3>     end
irb(main):026:2>   }
irb(main):027:1> end
=> #<Benchmark::Tms:0x00007fbdc3108be0 @label="", @real=0.33059399999910966, @cstime=0.0, @cutime=0.0, @stime=0.0, @utime=0.32000000000000006, @total=0.32000000000000006>

****edited to not be completely and totally incorrect in every way****

****编辑为在各方面都不完全不正确****

****added benchmarks****

****增加了基准****

回答by Tejasvi Manmatha

One command to convert date time to Unix format and then to string

一种将日期时间转换为 Unix 格式,然后再转换为字符串的命令

    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

finally strftime is used to format date

最后 strftime 用于格式化日期

Example:

例子:

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

回答by sbutterworth

This tells you the date of the number of seconds in future from the moment you execute the code.

这会告诉您从执行代码那一刻起未来的秒数日期。

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

puts(time)

投入(时间)

according to the current time I am answering the question it prints 047-05-14 05:16:16 +0000(1 billion seconds in future)

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

or if you want to count billion seconds from a particular time, it's in format Time.mktime(year, month,date,hours,minutes)

或者如果你想从特定时间计算十亿秒,它是格式 Time.mktime(year, month,date,hours,minutes)

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

puts("I would be 1 Billion seconds old on: "+time)

puts("我会老 10 亿秒:"+time)

回答by pjammer

If you wanted just a Date, you can do Date.strptime(invoice.date.to_s, '%s')where invoice.datecomes in the form of anFixnumand then converted to a String.

如果你只想要一个日期,你可以以 an 的形式来做Date.strptime(invoice.date.to_s, '%s'),然后转换为.invoice.dateFixnumString