If I have d = DateTime.now
, how do I convert 'd' into UTC (with the appropriate date)?
6 Answers
DateTime.now.new_offset(0)
will work in standard Ruby (i.e. without ActiveSupport).

- 15,182
- 3
- 44
- 45
-
3And this is actually the most correct answer to the question. – Ernest May 07 '12 at 19:53
-
2This should have more upvotes. DateTime is different to Time. I needed exactly this. – d11wtq Sep 28 '12 at 10:59
-
2`new_offset` method argument defaults to `0` already. So `DateTime.now.new_offset` may be used as well. – Cryptor Dec 18 '17 at 17:37
d = DateTime.now.utc
Oops!
That seems to work in Rails, but not vanilla Ruby (and of course that is what the question is asking)
d = Time.now.utc
Does work however.
Is there any reason you need to use DateTime
and not Time
? Time
should include everything you need:
irb(main):016:0> Time.now
=> Thu Apr 16 12:40:44 +0100 2009

- 36,066
- 13
- 81
- 92
-
Because I want the correct date for the conversion, ie, for GMT +10 can be ahead the next day... – Ash Apr 16 '09 at 11:29
-
2Time will do that for you just fine. Time includes the date part as well, not just the time of the day. Do Time.now.inspect to take a look. – DanSingerman Apr 16 '09 at 11:32
-
2
-
18Time is stored internally as the number of seconds and microseconds since the epoch, January 1, 1970 00:00 UTC. Date, internally, is represented as an Astronomical Julian Day Number, and DateTime is just plain weird (which is probably why Rails overrides it) – DanSingerman Apr 16 '09 at 11:44
Unfortunately, the DateTime class doesn't have the convenience methods available in the Time class to do this. You can convert any DateTime object into UTC like this:
d = DateTime.now
d.new_offset(Rational(0, 24))
You can switch back from UTC to localtime using:
d.new_offset(DateTime.now.offset)
where d
is a DateTime object in UTC time. If you'd like these as convenience methods, then you can create them like this:
class DateTime
def localtime
new_offset(DateTime.now.offset)
end
def utc
new_offset(Rational(0, 24))
end
end
You can see this in action in the following irb session:
d = DateTime.now.new_offset(Rational(-4, 24))
=> #<DateTime: 106105391484260677/43200000000,-1/6,2299161>
1.8.7 :185 > d.to_s
=> "2012-08-03T15:42:48-04:00"
1.8.7 :186 > d.localtime.to_s
=> "2012-08-03T12:42:48-07:00"
1.8.7 :187 > d.utc.to_s
=> "2012-08-03T19:42:48+00:00"
As you can see above, the initial DateTime object has a -04:00 offset (Eastern Time). I'm in Pacific Time with a -07:00 offset. Calling localtime
as described previously properly converts the DateTime object into local time. Calling utc
on the object properly converts it to a UTC offset.

- 611
- 6
- 4
You can set an ENV if you want your Time.now
and DateTime.now
to respond in UTC time.
require 'date'
Time.now #=> 2015-11-30 11:37:14 -0800
DateTime.now.to_s #=> "2015-11-30T11:37:25-08:00"
ENV['TZ'] = 'UTC'
Time.now #=> 2015-11-30 19:37:38 +0000
DateTime.now.to_s #=> "2015-11-30T19:37:36+00:00"

- 2,281
- 1
- 23
- 29
In irb:
>>d = DateTime.now
=> #<DateTime: 11783702280454271/4800000000,5/12,2299161>
>> "#{d.hour.to_i - d.zone.to_i}:#{d.min}:#{d.sec}"
=> "11:16:41"
will convert the time to the utc. But as posted if it is just Time you can use:
Time.now.utc
and get it straight away.

- 5,496
- 1
- 28
- 35