Konwersja znacznika czasu UTC na ISO 8601 w Rubim

85

Mam sygnaturę czasową w UTC

„2010-10-25 23:48:46 UTC”

Muszę przekonwertować go na ISO 8601

„2010-10-29 06: 09Z”

Dokumentacja jest myląca jak diabli - jak to zrobić najłatwiej?

ming yeow
źródło

Odpowiedzi:

185

Myślę, że próbujesz nas oszukać.

Data wejściowa pytania to 25 października 2010 r. , A data wyjściowa to 29 października 2010 r . Dobrze rozegrane!

Kontynuując ten wątek szukania nitek: twoje czasy są również zupełnie inne i brakuje ci sekund z czasu wyjściowego.

A teraz prawdziwa odpowiedź.

Najpierw jednak mały fakt: wynik ISO 8601 w Rubim jest podobny do wyniku „Połączonej daty i godziny” ze strony Wikipedii ISO 8601 .

Masz ciąg, więc musisz przekształcić go w Timeobiekt, z którym możesz zrobić to_time. Wtedy wystarczy wywołać iso8601ten obiekt, aby uzyskać wersję ISO 8601:

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

to_timeMetoda jest dzięki uprzejmości Rails, natomiast iso8601dzięki uprzejmości biblioteki standardowej Rubiego.

Ryan Bigg
źródło
7
Dobra odpowiedź, ale nie dostałem pierwszej części (czy to miał być humor?)
Mark Thomas
5
Cholera! przejrzeliście mój spisek, żeby was oszukać. = P Dzięki za świetną odpowiedź, zastanawiam się, dlaczego nie piszą tego po prostu w dokumentacji!
ming yeow
13
@Mark Thomas: tak, to miał być humor. Dał wejście i czas wyjścia, które nigdy nie pasowały. Tricksie mały hobbit!
Ryan Bigg
To działa, ale chociaż jego pytanie dotyczyło tego, jak to zrobić w rubinie, nie zakładało, że jest to w środowisku szynowym.
courimas
1
Powiązane, dzięki za wskazanie mi formatów „to_time” ~ Time.now.iso8601, takich jak „2010-10-25T23: 48: 46Z”, jeśli chcesz użyć „+00: 00” zamiast „Z” (które miałem do starszego systemu) Wydaje się, że Time.now.to_time.iso8601 to robi.
lucygenik
21

Po wielu eksperymentach stwierdziłem, że parser biblioteki Time jest lepszy niż DateTime, chociaż powody mi umykają w tej chwili. Z tym zastrzeżeniem, zawsze używam Time zamiast DateTime do tego rodzaju rzeczy, a dokumentacja Ruby jest również trudna do zrozumienia, dlaczego tak jest,

require 'time'
puts Time.parse("2010-10-25 23:48:46 UTC").iso8601
"2010-10-25T23:48:46Z"
Steeve McCauley
źródło
5
dobry czysty rubinowy roztwór. Po prostu chcę dodać, jeśli oryginalny czas nie jest UTC, możesz tego chcieć: w przeciwnym Time.parse("...").utc.iso8601razie otrzymasz czas z sufiksem +03:00lub inną wartość w zależności od oryginalnego ciągu czasu strefy czasowej. Mam na myśli zamiast Z.
akostadinov
4

Uwaga: przed zastosowaniem metody to_time musisz przekonwertować (przeanalizować) ciąg czasu na obiekt czasu.

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

Prawidłowa procedura:

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

irb> ut.iso8601
 => "2010-10-25T23:48:46+00:00" 
Aerodame
źródło
1

Dodanie odpowiedzi na to bardzo stare pytanie, ponieważ jeśli używasz Railsów, nie ma potrzeby konwertowania / analizowania go w sposób, w jaki radzą Ci inne odpowiedzi:

  • Jeśli jest to już sygnatura czasowa (np. Atrybut created_atlub updated_at), możesz bezpośrednio wywołać iso8601metodę z tym znacznikiem czasu (np object.created_at.iso8601.).
  • iso8601Sposób przyjmuje również liczbową argumentu wyświetlenie cyfry ułamkowe; użyłbyś tego, jeśli chcesz 2020-04-06T19:16:55.604Zzamiast 2020-04-06T19:16:55Z.

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

Allison
źródło