Ruby/Rails: converting a Date to a UNIX timestamp
How would I get a UNIX timestamp (number of seconds since 1970 GMT) from a Date object in a Rails app?
I know Time#to_i
returns a timestamp, but doing Date#to_time
and then getting the timestamp results in something that's off by about a month (not sure why...).
Any help is appreciated, thanks!
Edit: OK, I think I figured it out- I was processing a date several times in a loop, and each time the date was moved a little because of a time zone mismatch, ultimately leading to my timestamp being a month off. Still, I'd be inte开发者_JAVA百科rested in knowing if there's any way to do this without relying on Date#to_time
.
The code date.to_time.to_i
should work fine. The Rails console session below shows an example:
>> Date.new(2009,11,26).to_time
=> Thu Nov 26 00:00:00 -0800 2009
>> Date.new(2009,11,26).to_time.to_i
=> 1259222400
>> Time.at(1259222400)
=> Thu Nov 26 00:00:00 -0800 2009
Note that the intermediate DateTime object is in local time, so the timestamp might be several hours off from what you expect. If you want to work in UTC time, you can use DateTime's method "utc".
I get the following when I try it:
>> Date.today.to_time.to_i
=> 1259244000
>> Time.now.to_i
=> 1259275709
The difference between these two numbers is due to the fact that Date
does not store the hours, minutes or seconds of the current time. Converting a Date
to a Time
will result in that day, midnight.
Solution for Ruby 1.8 when you have an arbitrary DateTime object:
1.8.7-p374 :001 > require 'date'
=> true
1.8.7-p374 :002 > DateTime.new(2012, 1, 15).strftime('%s')
=> "1326585600"
The suggested options of using to_utc
or utc
to fix the local time offset does not work. For me I found using Time.utc()
worked correctly and the code involves less steps:
> Time.utc(2016, 12, 25).to_i
=> 1482624000 # correct
vs
> Date.new(2016, 12, 25).to_time.utc.to_i
=> 1482584400 # incorrect
Here is what happens when you call utc after using Date
....
> Date.new(2016, 12, 25).to_time
=> 2016-12-25 00:00:00 +1100 # This will use your system's time offset
> Date.new(2016, 12, 25).to_time.utc
=> 2016-12-24 13:00:00 UTC
...so clearly calling to_i
is going to give the wrong timestamp.
DateTime.new(2012, 1, 15).to_time.to_i
精彩评论