Làm cách nào để chuyển đổi DateTime.now sang UTC trong Ruby?


96

Nếu tôi có d = DateTime.now, làm cách nào để chuyển đổi 'd' thành UTC (với ngày thích hợp)?

Câu trả lời:


154

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 DateTimevà không Time? Timenê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

Bởi vì tôi muốn ngày chính xác cho việc chuyển đổi, tức là, đối với GMT +10 có thể đến trước ngày hôm sau ...
Ash

2
Thời gian sẽ làm điều đó cho bạn tốt. Thời gian cũng bao gồm phần ngày tháng, không chỉ thời gian trong ngày. Làm Time.now.inspect để xem xét.
DanSingerman

2
Ôi ngọt ngào. Vậy sự khác biệt giữa Date, Time và DateTime là gì?
Ash

18
Thời gian được lưu trữ bên trong dưới dạng số giây và micro giây kể từ kỷ nguyên, ngày 1 tháng 1 năm 1970 00:00 UTC. Date, trong nội bộ, được thể hiện như một thiên văn Julian Số Day, và DateTime là chỉ đơn giản lạ (mà có lẽ tại sao Rails ghi đè nó)
DanSingerman

168
DateTime.now.new_offset(0)

sẽ hoạt động trong Ruby tiêu chuẩn (tức là không có ActiveSupport).


3
Và đây thực sự là câu trả lời chính xác nhất cho câu hỏi.
Ernest

2
Điều này sẽ có nhiều ủng hộ hơn. DateTime khác với Time. Tôi cần chính xác điều này.
d11wtq

1
new_offsetđối số phương thức mặc định là 0đã có. Vì vậy, DateTime.now.new_offsetcũng có thể được sử dụng.
Cryptor

8

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 dlà 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 localtimenhư đượ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.


5

Hãy thử điều này, hoạt động trong Ruby :

DateTime.now.to_time.utc

4

Bạn có thể đặt ENV nếu bạn muốn Time.nowDateTime.nowphả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"

2

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.


1

Biểu diễn chuỗi của DateTime có thể được phân tích cú pháp bởi lớp Thời gian.

> Time.parse(DateTime.now.to_s).utc
=> 2015-10-06 14:53:51 UTC
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.