Convert To/From Datetime and Time in Ruby

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



Leave a reply



Submit