Chuyển đổi dấu thời gian UTC thành ISO 8601 trong Ruby


85

Tôi có một dấu thời gian ở UTC

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

Tôi cần chuyển đổi nó thành ISO 8601

"2010-10-29 06: 09Z"

Tài liệu thật khó hiểu - cách dễ nhất để làm điều đó là gì?

Câu trả lời:


185

Tôi nghĩ bạn đang cố lừa chúng tôi.

Ngày nhập cho câu hỏi của bạn là ngày 25 tháng 10 năm 2010 , trong khi ngày đầu ra là ngày 29 tháng 10 năm 2010 . Chơi tốt!

Tiếp tục chủ đề chọn nit này: thời gian của bạn cũng hoàn toàn khác và bạn đang bỏ lỡ giây so với thời gian xuất.

Bây giờ cho câu trả lời thực sự.

Tuy nhiên, một chút thực tế đầu tiên: đầu ra ISO 8601 trong Ruby tương tự như đầu ra "Ngày và giờ kết hợp" từ trang Wikipedia của ISO 8601 .

Bạn có một chuỗi và vì vậy bạn sẽ cần chuyển đổi nó thành một Timeđối tượng mà bạn có thể thực hiện to_time. Sau đó, việc đơn giản là gọi iso8601đối tượng đó nhận phiên bản ISO 8601:

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

Các to_timephương pháp là biếu không của Rails, trong khi iso8601là biếu không của thư viện chuẩn của Ruby.


7
Tốt câu trả lời, nhưng tôi đã không nhận được phần đầu tiên (là nghĩa vụ phải được sự hài hước?)
Mark Thomas

5
Chỉ trích! bạn đã thấy qua âm mưu của tôi để lừa các bạn. = P Cảm ơn câu trả lời tuyệt vời, tôi tự hỏi tại sao họ không viết điều đó trong tài liệu!
ming yeow

13
@Mark Thomas: vâng nó được cho là hài hước. Anh ấy đã đưa ra một đầu vào và một thời gian đầu ra không bao giờ khớp nhau. Thằng Hobbit nhỏ xíu!
Ryan Bigg

Điều này hoạt động, nhưng mặc dù câu hỏi của anh ta hỏi làm thế nào để làm điều đó trong ruby, nó không cho rằng nó ở trong môi trường đường ray.
courtimas

1
Có liên quan, cảm ơn vì đã chỉ cho tôi định dạng 'to_time' ~ Time.now.iso8601 như "2010-10-25T23: 48: 46Z", nếu bạn muốn sử dụng '+00: 00' thay vì 'Z' (tôi đã có cho hệ thống kế thừa) Time.now.to_time.iso8601 dường như thực hiện việc này.
lucygenik

21

Sau nhiều thử nghiệm, tôi thấy trình phân tích cú pháp của thư viện Thời gian tốt hơn DateTime, mặc dù lý do khiến tôi không thể tránh khỏi lúc này. Với lời cảnh báo đó, tôi luôn sử dụng Time thay vì DateTime cho loại nội dung này và tài liệu ruby ​​cũng khó tìm hiểu tại sao lại như vậy,

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

5
dung dịch ruby ​​tinh khiết tốt. Chỉ muốn thêm, nếu thời gian gốc không phải là UTC, bạn có thể muốn điều này Time.parse("...").utc.iso8601:, tùy chỉnh khác, bạn sẽ nhận được thời gian kèm theo +03:00hoặc một số giá trị khác tùy thuộc vào múi giờ chuỗi thời gian gốc được cung cấp. Ý tôi là thay vì Z.
akostadinov

4

Lưu ý: bạn phải chuyển đổi (phân tích cú pháp) một chuỗi thời gian thành một đối tượng thời gian trước khi bạn có thể áp dụng phương thức 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

Quy trình đúng:

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

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

1

Thêm một câu trả lời cho câu hỏi siêu cũ này vì nếu bạn đang sử dụng Rails, không cần phải chuyển đổi / phân tích cú pháp nó theo cách mà các câu trả lời khác ở đây yêu cầu bạn làm:

  • Nếu nó đã là một dấu thời gian (ví dụ: một created_athoặc updated_atthuộc tính), bạn có thể gọi trực tiếpiso8601 phương thức trên dấu thời gian đó (ví dụ object.created_at.iso8601:).
  • Các iso8601phương pháp cũng chấp nhận một đối số số để hiển thị chữ số phân đoạn; bạn sẽ sử dụng điều này nếu bạn muốn 2020-04-06T19:16:55.604Zthay vì 2020-04-06T19:16:55Z.

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

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.