Câu trả lời:
d = DateTime.now.utc
Giáo sư!
Điều đó dường như hoạt động trong Rails, nhưng không phải vani Ruby (và tất nhiên đó là những gì câu hỏi đang đặt ra)
d = Time.now.utc
Tuy nhiên, không hoạt động.
Có lý do gì bạn cần sử dụng DateTime
và không Time
? Time
nên bao gồm mọi thứ bạn cần:
irb(main):016:0> Time.now
=> Thu Apr 16 12:40:44 +0100 2009
DateTime.now.new_offset(0)
sẽ hoạt động trong Ruby tiêu chuẩn (tức là không có ActiveSupport).
new_offset
đối số phương thức mặc định là 0
đã có. Vì vậy, DateTime.now.new_offset
cũng có thể được sử dụng.
Thật không may, lớp DateTime không có sẵn các phương thức tiện lợi trong lớp Time để thực hiện việc này. Bạn có thể chuyển đổi bất kỳ đối tượng DateTime nào thành UTC như sau:
d = DateTime.now
d.new_offset(Rational(0, 24))
Bạn có thể chuyển lại từ UTC sang localtime bằng cách sử dụng:
d.new_offset(DateTime.now.offset)
nơi d
là một đối tượng DateTime trong UTC thời gian. Nếu bạn muốn đây là các phương pháp tiện lợi, thì bạn có thể tạo chúng như sau:
class DateTime
def localtime
new_offset(DateTime.now.offset)
end
def utc
new_offset(Rational(0, 24))
end
end
Bạn có thể thấy điều này hoạt động trong phiên irb sau:
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"
Như bạn thấy ở trên, đối tượng DateTime ban đầu có độ lệch -04: 00 (Giờ miền Đông). Tôi đang ở Giờ Thái Bình Dương với chênh lệch -07: 00. Việc gọi localtime
như được mô tả trước đó sẽ chuyển đổi đúng cách đối tượng DateTime thành giờ địa phương. Gọi utc
đối tượng đúng cách sẽ chuyển đổi nó thành bù UTC.
Bạn có thể đặt ENV nếu bạn muốn Time.now
và DateTime.now
phản hồi trong thời gian UTC.
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"
Trong 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"
sẽ chuyển đổi thời gian thành utc. Nhưng như đã đăng nếu đó chỉ là Thời gian bạn có thể sử dụng:
Time.now.utc
và lấy nó ngay lập tức.