ฉันจะแปลง DateTime.now เป็น UTC ใน Ruby ได้อย่างไร


98

ถ้ามีฉันd = DateTime.nowจะแปลง 'd' เป็น UTC ได้อย่างไร (ด้วยวันที่ที่เหมาะสม)

คำตอบ:


156

d = DateTime.now.utc

อ๊ะ!

ดูเหมือนจะใช้งานได้ใน Rails แต่ไม่ใช่วานิลลา Ruby (และแน่นอนนั่นคือสิ่งที่ถาม)

d = Time.now.utc

ทำงานอย่างไรก็ตาม

มีเหตุผลใดที่คุณต้องใช้DateTimeไม่ใช่Timeหรือ? Timeควรรวมทุกสิ่งที่คุณต้องการ:

irb(main):016:0> Time.now
=> Thu Apr 16 12:40:44 +0100 2009

เพราะฉันต้องการวันที่ที่ถูกต้องสำหรับการแปลงเช่นสำหรับ GMT +10 สามารถล่วงหน้าได้ในวันถัดไป ...
เถ้า

2
เวลาจะทำเพื่อคุณได้ดี เวลารวมถึงส่วนของวันที่ด้วยไม่ใช่แค่ช่วงเวลาของวัน ทำ Time.now.inspect เพื่อดู
DanSingerman

2
โอ้หวาน. แล้ว Date, Time และ DateTime ต่างกันอย่างไร?
เถ้า

18
เวลาจะถูกเก็บไว้ภายในเป็นจำนวนวินาทีและไมโครวินาทีนับตั้งแต่ยุค 1 มกราคม 1970 00:00 UTC วันที่ภายในแสดงเป็นหมายเลขวันจูเลียนทางดาราศาสตร์และ DateTime เป็นเรื่องแปลก ๆ (ซึ่งอาจเป็นสาเหตุที่ Rails แทนที่)
DanSingerman

169
DateTime.now.new_offset(0)

จะทำงานใน Ruby มาตรฐาน (กล่าวคือไม่มี ActiveSupport)


3
และนี่เป็นคำตอบที่ถูกต้องที่สุดสำหรับคำถามนี้
เออร์เนสต์

2
สิ่งนี้ควรมีการโหวตเพิ่มขึ้น DateTime ต่างจาก Time ฉันต้องการสิ่งนี้จริงๆ
d11wtq

1
new_offsetอาร์กิวเมนต์วิธีการมีค่าเริ่มต้นเป็น0แล้ว ดังนั้นDateTime.now.new_offsetอาจจะใช้เช่นกัน
Cryptor

8

น่าเสียดายที่คลาส DateTime ไม่มีวิธีอำนวยความสะดวกในคลาส Time ให้ทำเช่นนี้ คุณสามารถแปลงวัตถุ DateTime เป็น UTC ได้ดังนี้:

d = DateTime.now
d.new_offset(Rational(0, 24))

คุณสามารถเปลี่ยนกลับจาก UTC เป็นเวลาท้องถิ่นได้โดยใช้:

d.new_offset(DateTime.now.offset)

dวัตถุ DateTime อยู่ที่ไหนในเวลา UTC หากคุณต้องการสิ่งเหล่านี้เป็นวิธีอำนวยความสะดวกคุณสามารถสร้างได้ดังนี้:

class DateTime
  def localtime
    new_offset(DateTime.now.offset)
  end

  def utc
    new_offset(Rational(0, 24))
  end
end

คุณสามารถเห็นสิ่งนี้ในการดำเนินการในเซสชัน irb ต่อไปนี้:

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" 

ดังที่คุณเห็นด้านบนอ็อบเจ็กต์ DateTime เริ่มต้นมีออฟเซ็ต -04: 00 (เวลาตะวันออก) ฉันอยู่ในเวลาแปซิฟิกโดยมีออฟเซ็ต -07: 00 การโทรlocaltimeตามที่อธิบายไว้ก่อนหน้านี้จะแปลงวัตถุ DateTime เป็นเวลาท้องถิ่นอย่างถูกต้อง การเรียกutcใช้วัตถุจะแปลงเป็น UTC offset อย่างถูกต้อง



4

คุณสามารถตั้งค่า ENV ได้หากคุณต้องการTime.nowและDateTime.nowตอบกลับในเวลา 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

ใน 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"

จะแปลงเวลาเป็น utc แต่ตามที่โพสต์ไว้ว่าเป็นเพียงเวลาที่คุณสามารถใช้ได้:

Time.now.utc

และรับทันที


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.