How do I Convert DateTime.now to UTC in Ruby?

前端 未结 7 1425
既然无缘
既然无缘 2020-12-01 04:24

If I have d = DateTime.now, how do I convert \'d\' into UTC (with the appropriate date)?

相关标签:
7条回答
  • 2020-12-01 04:34

    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.

    0 讨论(0)
  • 2020-12-01 04:34

    The string representation of a DateTime can be parsed by the Time class.

    > Time.parse(DateTime.now.to_s).utc
    => 2015-10-06 14:53:51 UTC
    
    0 讨论(0)
  • 2020-12-01 04:35
    DateTime.now.new_offset(0)
    

    will work in standard Ruby (i.e. without ActiveSupport).

    0 讨论(0)
  • 2020-12-01 04:35

    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"
    
    0 讨论(0)
  • 2020-12-01 04:48

    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
    
    0 讨论(0)
  • 2020-12-01 04:48

    Try this, works in Ruby:

    DateTime.now.to_time.utc
    
    0 讨论(0)
提交回复
热议问题