Перетворення позначки часу UTC на ISO 8601 у Ruby


85

У мене є мітка часу в UTC

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

Мені потрібно перетворити його на ISO 8601

"2010-10-29 06: 09Z"

Документація, як пекло, заплутана - який найпростіший спосіб це зробити?

Відповіді:


185

Я думаю, ти намагаєшся нас обдурити.

Дата введення вашого запитання - 25 жовтня 2010 року , тоді як вихідна - 29 жовтня 2010 року . Гарно зіграно!

Продовжуючи цю нитку збору ніт: ваш час також абсолютно інший, і ви втрачаєте секунди від вихідного часу.

Тепер за правдивою відповіддю.

Спочатку трохи фактично: вихідний файл ISO 8601 у Ruby подібний до "Комбінованої дати та часу", виведеного на сторінці Вікіпедії ISO 8601 .

У вас є рядок, і тому вам потрібно буде перетворити його в Timeоб’єкт, з яким ви можете зробити to_time. Тоді справа лише в тому, щоб зателефонувати iso8601цьому об’єкту, щоб отримати версію ISO 8601:

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

to_timeМетод люб'язно Rails, в той час як iso8601люб'язно стандартної бібліотеки Рубі.


7
Гарна відповідь, але першої частини я не отримав (це мав бути гумор?)
Марк Томас

5
Блін! Ви переглянули мій змову, щоб обдурити вас, люди. = P Дякую за чудову відповідь, цікаво, чому вони не просто пишуть це у документації!
ming yeow

13
@ Марк Томас: так, це мав бути гумор. Він дав час введення та виведення, який ніколи не збігався. Трікі маленький хоббіт!
Райан Бігг,

Це спрацьовує, але, хоча його питання задавало питання, як це зробити в рубіні, він не припускав, що це було в середовищі рейок.
courtimas 02

1
Пов’язано, дякую, що вказали мені на формати 'to_time' ~ Time.now.iso8601, такі як "2010-10-25T23: 48: 46Z", якщо ви хочете використовувати "+00: 00" замість "Z" (що я мав для для застарілої системи) Time.now.to_time.iso8601, здається, робить це.
lucygenik

21

Після довгих експериментів я вважаю, що синтаксичний аналізатор бібліотеки Time кращий за 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.
Акостадінов

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, немає необхідності перетворювати / аналізувати його так, як кажуть вам інші відповіді тут:

  • Якщо це вже мітка часу (наприклад, а 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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.