Convert to/from DateTime and Time in Ruby
You'll need two slightly different conversions.
To convert from Time
to DateTime
you can amend the Time class as follows:
require 'date'
class Time
def to_datetime
# Convert seconds + microseconds into a fractional number of seconds
seconds = sec + Rational(usec, 10**6)
# Convert a UTC offset measured in minutes to one measured in a
# fraction of a day.
offset = Rational(utc_offset, 60 * 60 * 24)
DateTime.new(year, month, day, hour, min, seconds, offset)
end
end
Similar adjustments to Date will let you convert DateTime
to Time
.
class Date
def to_gm_time
to_time(new_offset, :gm)
end
def to_local_time
to_time(new_offset(DateTime.now.offset-offset), :local)
end
private
def to_time(dest, method)
#Convert a fraction of a day to a number of microseconds
usec = (dest.sec_fraction * 60 * 60 * 24 * (10**6)).to_i
Time.send(method, dest.year, dest.month, dest.day, dest.hour, dest.min,
dest.sec, usec)
end
end
Note that you have to choose between local time and GM/UTC time.
Both the above code snippets are taken from O'Reilly's Ruby Cookbook. Their code reuse policy permits this.
Ruby date and time conversion from one format to other
require 'date'
def convert_date(old_date)
DateTime.strptime(old_date, '%m/%d/%Y:%H:%M:%S').strftime("%Y%m%d%H%M%S")
end
convert_date('02/16/2015:19:16:07')
#-> 20150216191607
How to convert date and time into datetime/timestamp
You would use strptime
on Time
or DateTime
if you need timestamp:
require 'time'
csv_hash = {"date"=>"23/04/16", "day"=>"SATURDAY", "time"=>"17:06"}
time_from_csv = Time.strptime("#{csv_hash["date"]}:#{csv_hash["time"]}", '%d/%m/%y:%H:%M') # 2016-04-23 17:06:00 +0000
timestamp = time_from_csv.to_i # 1461423960
Take a read at the documentation for Time#strptime
If you want DateTime
do DateTime.strptime(...)
convert String to DateTime
DateTime.strptime allows you to specify the format and convert a String to a DateTime.
DateTime to Time conversion
to_time
does work. It converts both times to your local timezone, but that makes no difference when subtracting them. This definitely works:
date_time2.to_time - date_time1.to_time
Your real problem is that you're not parsing the PM, which is why your difference ends up off by 12 hours! Look at your example
date_time1 = DateTime.strptime("01-15-2014 01:11:12 PM", '%m-%d-%Y %l:%M:%S')
# date_time1: 2014-01-15T01:11:12+00:00
You are asking for 1:11 PM UTC, but it is telling you that date_time1
is 1:11 AM. You need to add to your format string
'%m-%d-%Y %l:%M:%S %p'
Here's an example from my timezone if you're still skeptical.
d1 = DateTime.now
#<DateTime: 2014-06-18T11:47:22-04:00 ((2456827j,56842s,704352659n),-14400s,2299161j)>
d1.to_time - DateTime.strptime("06-18-2014 03:47:00 PM", '%m-%d-%Y %l:%M:%S %p').to_time
# 22.704352659
Note that 3:47 PM UTC is 11:47 AM in UTC-4 (the timezone of d1
), so ~22 seconds is the correct answer.
EDIT
If, however, you want to change them to be in the same timezone before calculating the offset, you can do the following:
date_time2.to_time - (date_time1 - date_time2.offset).to_time
Ruby DateTime and epoch conversion
Convert to Time with .to_time
and then to Unix Time with to_i
. For example:
created_at = ModelName.where("created_at >= ? ", Time.zone.now).pluck(:created_at)
created_at.to_time.to_i
What's the best way to convert a Date to a DateTime in the current timezone in Rails 4?
Here's the best answer I could come up with.
Time.zone.at(Date.current.to_time).to_datetime
Transform DateTime into simple Date in Ruby on Rails
DateTime#to_date
does exist with ActiveSupport:
$ irb
>> DateTime.new.to_date
NoMethodError: undefined method 'to_date' for #<DateTime: -1/2,0,2299161>
from (irb):1
>> require 'active_support/core_ext'
=> true
>> DateTime.new.to_date
=> Mon, 01 Jan -4712
Weird Ruby Behavior in DateTime to Time conversion
According to the Rails documentation for DateTime.to_time()
,
If self has an offset other than 0, self will just be returned unaltered
To change to a 0 offset, use DateTime.utc()
.
1.9.3p194 :005 > t3=t2.utc
=> Sat, 30 Jun 2012 20:43:21 +0000
1.9.3p194 :006 > t3.offset
=> (0/1)
1.9.3p194 :007 > t4=t3.to_time
=> 2012-06-30 20:43:21 UTC
1.9.3p194 :008 > t4.class
=> Time
Related Topics
Eoferror: End of File Reached Issue With Net::Http
Class ≪≪ Self VS Self.Method With Ruby: What's Better
Ruby Templates: How to Pass Variables into Inlined Erb
To Use Self. or Not.. in Rails
When Do I Need to Restart Server in Rails
How to Convert Json to a Ruby Hash
Ruby/Rails - Change the Timezone of a Time, Without Changing the Value
Why Not Use Shared Activerecord Connections For Rspec + Selenium
How to Check a Checkbox in Capybara
Undefined Method 'Visit' When Using Rspec and Capybara in Rails
Devise Custom Routes and Login Pages
Uniq by Object Attribute in Ruby
Difference Between $Stdout and Stdout in Ruby
How to Stub Things in Minitest
How to Group by Count in Array Without Using Loop