การแปลงการประทับเวลา UTC เป็น ISO 8601 ใน Ruby


86

ฉันมีการประทับเวลาที่อยู่ใน UTC

"2010-10-25 23:48:46 UTC"

ฉันต้องการแปลงเป็น ISO 8601

"2010-10-29 06: 09Z"

เอกสารนั้นสับสนราวกับนรก - วิธีที่ง่ายที่สุดในการทำเช่นนั้นคืออะไร?

คำตอบ:


187

ฉันคิดว่าคุณกำลังพยายามหลอกเรา

วันที่เข้ากับคำถามของคุณคือ25 ตุลาคม 2010ขณะที่การส่งออกเป็นวันที่ 29ของการเดือนตุลาคม, ปี 2010 เล่นดี!

ดำเนินการต่อในเธรดการเลือกไนท์นี้: เวลาของคุณก็แตกต่างกันอย่างสิ้นเชิงและคุณพลาดวินาทีจากเวลาที่ส่งออก

ตอนนี้สำหรับคำตอบที่แท้จริง

เล็ก ๆ น้อย ๆ factoid แรกแม้ว่า: การส่งออกมาตรฐาน ISO 8601 ในทับทิมมีความคล้ายคลึงกับ "วันที่และเวลารวม" เอาท์พุทจากISO 8601 หน้าวิกิพีเดีย

คุณได้มีสตริงและเพื่อให้คุณจะต้องแปลงเป็นวัตถุที่คุณสามารถทำอะไรกับTime to_timeจากนั้นก็เป็นเพียงเรื่องของการเรียกร้องiso8601ให้วัตถุนั้นรับเวอร์ชัน ISO 8601:

"2010-10-25 23:48:46 UTC".to_time.iso8601

to_timeวิธีคือมารยาทของทางรถไฟในขณะที่iso8601เป็นมารยาทของไลบรารีมาตรฐานของรูบี้


7
คำตอบที่ดี แต่ฉันไม่ได้รับส่วนแรก (นั่นควรจะเป็นอารมณ์ขันหรือไม่)
Mark Thomas

5
ประณาม! คุณเห็นแผนการของฉันเพื่อหลอกล่อคนอื่น ๆ = P ขอบคุณสำหรับคำตอบที่ยอดเยี่ยมฉันสงสัยว่าทำไมพวกเขาไม่เขียนสิ่งนั้นในเอกสาร!
หมิงโหยว

13
@ Mark Thomas: ใช่มันควรจะเป็นเรื่องตลก เขาให้อินพุตและเวลาเอาต์พุตที่ไม่ตรงกันเลยทีเดียว Tricksie ฮอบบิทตัวน้อย!
Ryan Bigg

วิธีนี้ใช้ได้ผล แต่ถึงแม้คำถามของเขาจะถามว่าทำอย่างไรในทับทิม แต่ก็ไม่ได้คิดว่ามันอยู่ในสภาพแวดล้อมของราง
Courtsimas

1
ขอบคุณที่ชี้ฉันที่รูปแบบ "to_time" ~ Time.now.iso8601 เช่น "2010-10-25T23: 48: 46Z" ถ้าคุณต้องการใช้ "+00: 00" แทน "Z" (ซึ่งฉันมี สำหรับระบบเดิม) ดูเหมือนว่า Time.now.to_time.iso8601 จะทำเช่นนี้
lucygenik

21

หลังจากการทดลองหลายครั้งฉันพบว่าตัวแยกวิเคราะห์ของไลบรารีเวลาดีกว่า DateTime แม้ว่าเหตุผลจะหนีฉันไปในขณะนี้ก็ตาม ด้วยข้อแม้นั้นฉันมักจะใช้ Time แทนที่จะเป็น DateTime สำหรับสิ่งประเภทนี้และเอกสารทับทิมก็ยากที่จะเข้าใจว่าทำไมถึงเป็นเช่นนั้น

require 'time'
puts Time.parse("2010-10-25 23:48:46 UTC").iso8601
"2010-10-25T23:48:46Z"

5
สารละลายทับทิมบริสุทธิ์ที่ดี เพียงแค่ต้องการเพิ่มหากเวลาเดิมไม่ใช่ UTC คุณอาจต้องการสิ่งนี้: Time.parse("...").utc.iso8601otherwize คุณจะได้รับเวลาที่ต่อท้ายด้วย+03:00หรือค่าอื่น ๆ ขึ้นอยู่กับเขตเวลาดั้งเดิมที่กำหนดด้วย ฉันหมายถึงแทนZ.
akostadinov

4

หมายเหตุ: คุณต้องแปลง (แยกวิเคราะห์) สตริงเวลาเป็นวัตถุเวลาก่อนจึงจะสามารถใช้เมธอด to_time ได้

ruby-1.9.2-p180 :016 > "2010-10-25 23:48:46 UTC".to_time.iso8601
NoMethodError: undefined method `to_time' for "2010-10-25 23:48:46 UTC":String
    from (irb):16

ขั้นตอนที่ถูกต้อง:

irb> ut = DateTime.parse("2010-10-25 23:48:46 UTC")

irb> ut.iso8601
 => "2010-10-25T23:48:46+00:00" 

1

การเพิ่มคำตอบให้กับคำถามเก่าสุด ๆ นี้เพราะหากคุณใช้ Rails ไม่จำเป็นต้องแปลง / แยกวิเคราะห์ด้วยวิธีที่คำตอบอื่น ๆ ที่นี่บอกให้คุณทำ:

  • หากเป็นการประทับเวลาอยู่แล้ว (เช่น a created_atหรือupdated_atแอตทริบิวต์) คุณสามารถเรียกใช้เมธอดในการประทับเวลานั้นได้โดยตรงiso8601 (เช่นobject.created_at.iso8601)
  • iso8601วิธียังยอมรับอาร์กิวเมนต์ที่เป็นตัวเลขจะแสดงตัวเลขที่เป็นเศษ; คุณจะใช้นี้ถ้าคุณต้องการแทน2020-04-06T19:16:55.604Z2020-04-06T19:16:55Z

https://api.rubyonrails.org/v5.2.4/classes/ActiveSupport/TimeWithZone.html#method-i-iso8601

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