Преобразование метки времени UTC в ISO 8601 в Ruby

86

У меня есть отметка времени в формате UTC

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

Мне нужно преобразовать его в ISO 8601

"2010-10-29 06: 09Z"

Документация чертовски запутана - как это сделать проще всего?

мин да
источник

Ответы:

187

Я думаю, вы пытаетесь нас обмануть.

Дата ввода на ваш вопрос является 25 октября 2010 года , в то время как выход является двадцать девятого октября 2010 года . Отлично сработано!

Продолжая эту тему для придирки: ваше время также совершенно другое, и вы упускаете секунды из времени вывода.

Теперь верный ответ.

Сначала немного фактов: вывод ISO 8601 в Ruby аналогичен выводу «Объединенная дата и время» со страницы Wikipedia ISO 8601 .

У вас есть строка, и вам нужно преобразовать ее в Timeобъект, с которым вы можете работать to_time. Затем нужно просто вызвать iso8601этот объект, чтобы получить версию ISO 8601:

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

Этот to_timeметод любезно предоставлен Rails, тогда как iso8601это любезно предоставлено стандартной библиотекой Ruby.

Райан Бигг
источник
7
Хороший ответ, но я не понял первую часть (это должен был быть юмор?)
Марк Томас
5
Черт! Вы видели мой заговор, чтобы обмануть вас, ребята. = P Спасибо за отличный ответ, мне интересно, почему они просто не пишут об этом в документации!
ming yeow
13
@Mark Thomas: да, это должен был быть юмор. Он дал время входа и выхода, которые никогда не совпадали. Маленький хитрый хоббит!
Райан Бигг,
Это работает, но хотя его вопрос спрашивал, как это сделать в Ruby, он не предполагал, что это было в среде rails.
Courtimas
1
В связи с этим, спасибо, что указал мне на форматы 'to_time' ~ Time.now.iso8601, такие как «2010-10-25T23: 48: 46Z», если вы хотите использовать «+00: 00» вместо «Z» (который у меня был to для устаревшей системы) Time.now.to_time.iso8601, похоже, делает это.
lucygenik
21

После долгих экспериментов я обнаружил, что синтаксический анализатор библиотеки Time лучше, чем DateTime, хотя на данный момент причины ускользают от меня. С этой оговоркой, я всегда использую Time, а не DateTime для такого рода вещей, и документацию по Ruby также трудно понять, почему это так,

require 'time'
puts Time.parse("2010-10-25 23:48:46 UTC").iso8601
"2010-10-25T23:48:46Z"
Стив МакКоли
источник
5
хороший чистый раствор рубина. Просто хочу добавить, если исходное время не является UTC, вам может понадобиться следующее:, Time.parse("...").utc.iso8601иначе вы получите суффикс времени +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" 
Aerodame
источник
1

Добавление ответа на этот супер-старый вопрос, потому что, если вы используете Rails, нет необходимости преобразовывать / анализировать его так, как вам говорят другие ответы здесь:

  • Если это уже метка времени (например, атрибут created_atили updated_at), вы можете напрямую вызвать iso8601метод для этой метки времени (например,object.created_at.iso8601 ).
  • iso8601Метод также принимает числовой аргумент для отображения цифр дробной части; вы могли бы использовать это, если хотите, 2020-04-06T19:16:55.604Zвместо 2020-04-06T19:16:55Z.

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

Эллисон
источник