Convert to/from DateTime and Time in Ruby Convert to/from DateTime and Time in Ruby ruby ruby

Convert to/from DateTime and Time in Ruby


require 'time'require 'date't = Time.nowd = DateTime.nowdd = DateTime.parse(t.to_s)tt = Time.parse(d.to_s)


As an update to the state of the Ruby ecosystem, Date, DateTime and Time now have methods to convert between the various classes. Using Ruby 1.9.2+:

pry[1] pry(main)> ts = 'Jan 1, 2000 12:01:01'=> "Jan 1, 2000 12:01:01"[2] pry(main)> require 'time'=> true[3] pry(main)> require 'date'=> true[4] pry(main)> ds = Date.parse(ts)=> #<Date: 2000-01-01 (4903089/2,0,2299161)>[5] pry(main)> ds.to_date=> #<Date: 2000-01-01 (4903089/2,0,2299161)>[6] pry(main)> ds.to_datetime=> #<DateTime: 2000-01-01T00:00:00+00:00 (4903089/2,0,2299161)>[7] pry(main)> ds.to_time=> 2000-01-01 00:00:00 -0700[8] pry(main)> ds.to_time.class=> Time[9] pry(main)> ds.to_datetime.class=> DateTime[10] pry(main)> ts = Time.parse(ts)=> 2000-01-01 12:01:01 -0700[11] pry(main)> ts.class=> Time[12] pry(main)> ts.to_date=> #<Date: 2000-01-01 (4903089/2,0,2299161)>[13] pry(main)> ts.to_date.class=> Date[14] pry(main)> ts.to_datetime=> #<DateTime: 2000-01-01T12:01:01-07:00 (211813513261/86400,-7/24,2299161)>[15] pry(main)> ts.to_datetime.class=> DateTime


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

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

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.