How to convert a unix timestamp (seconds since epo

2019-01-09 22:16发布

问题:

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

回答1:

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

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


回答2:

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

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

# ~ % 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>


回答3:

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

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.

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

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 class's, the #== method takes care of this for you), but the #to_s method 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.

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.at and it will return the result in the time zone of the argument:

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

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



回答4:

One command to convert date time to Unix format and then to 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

finally strftime is used to format date

Example:

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


回答5:

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)

or if you want to count billion seconds from a particular time, it's in format 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)



回答6:

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