From: Walton Hoops Date: 2013-07-03T13:22:28+09:00 Subject: Re: How can I add minutes,seconds and hours to a DateTime object? On 7/2/2013 4:33 PM, Mike Stok wrote: > On 2013-07-02, at 3:41 PM, Love U Ruby wrote: > >> finally I came up with as below : >> >> require 'date' >> >> text_t = '2:12:03 PM ET' >> dt = DateTime.parse(text_t, '%I:%M %p %Z') >> # => #> ((2456477j,51123s,0n),+0s,2299161j)> >> dt.to_s >> # => "2013-07-03T14:12:03+00:00" # !> invalid offset is ignored >> dh = Date._strptime(dt.to_s,'%Y-%m-%dT%H:%M:%S%z') >> # => {:year=>2013, >> # :mon=>7, >> # :mday=>3, >> # :hour=>14, >> # :min=>12, >> # :sec=>3, >> # :zone=>"+00:00", >> # :offset=>0} >> >> dh[:hour] += 30 # => 44 >> dh >> # => {:year=>2013, >> # :mon=>7, >> # :mday=>3, >> # :hour=>44, >> # :min=>12, >> # :sec=>3, >> # :zone=>"+00:00", >> # :offset=>0} >> >> dh.values[0..-2].join(" ") >> # => "2013 7 3 44 12 3 +00:00" >> DateTime.ordinal(*dh.values[0..-3]) >> # => #> ((2456300j,13452s,0n),+0s,2299161j)> >> > ratdog:tmp mike$ pry > [1] pry(main)> require 'date' > => false > [2] pry(main)> dt = DateTime.parse('2:12:03 PM ET', '%I:%M %p %Z') > => # > [3] pry(main)> dt + (30.0 / 24) # days > => # > Both approaches make me nervous. The first because your parsing a date where the time is 44:00 (clearly an invalid date), which at best I believe is undocumented behavior, and more likely is exploiting a bug that may be fixed at a later date. The is Mike's is probably fine, but makes me worry about rounding errors for some values. Instead I'd do the math using Time, which uses seconds instead of fractions of days: irb(main):006:0> now = DateTime.now.to_time => 2013-07-02 22:09:19 -0600 irb(main):007:0> hours = 2 => 2 irb(main):008:0> minutes = 5 => 5 irb(main):010:0> now + (hours * 60 * 60) + minutes * 60 => 2013-07-03 00:14:19 -0600 Ideally the Stdlib would have a TimeSpan class which could be added and subtracted from DateTime, or be the result of subtracting 2 DateTimes. Would be a good idea for a gem.