Jak przekonwertować uniksowy znacznik czasu (w sekundach od epoki) na Ruby DateTime?
369
DateTime.strptime
może obsłużyć sekundy od epoki. Liczba musi zostać przekonwertowana na ciąg:
require 'date'
DateTime.strptime("1318996912",'%s')
%Q
tho ” .Time
jest to konieczne zamiastDateTime
. Skorzystaj,Time.strptime("1318996912345",'%Q').to_f
a zobaczysz milisekundy zachowane, aDateTime.strptime("1318996912345",'%Q').to_f
nie zachowane.Przepraszamy, krótka chwila niepowodzenia synapsy. Oto prawdziwa odpowiedź.
Krótki przykład (uwzględnia aktualną strefę czasową systemu):
Dalsza aktualizacja (dla UTC):
Ostatnia aktualizacja : Przeprowadziłem testy porównawcze najlepszych rozwiązań w tym wątku, pracując nad usługą HA tydzień lub dwa lata temu, i byłem zaskoczony, że
Time.at(..)
przewyższa toDateTime.strptime(..)
(aktualizacja: dodałem więcej testów porównawczych).źródło
Time.at
osiąga lepsze wynikiDateTime.strptime
. Ten ostatni musi przeanalizować ciąg znaków, który jest na ogół znacznie wolniejszy niż bezpośrednie pobieranie liczby.DateTime.strptime
ponieważ tworzy dwa nowe ciągi w każdej iteracji, co jest bardzo drogie. To nie tylko parsowanie łańcucha, jak powiedziałObsługa stref czasowych
Chcę tylko wyjaśnić, chociaż zostało to skomentowane, aby przyszli ludzie nie przegapili tego bardzo ważnego rozróżnienia.
wyświetla wartość zwracaną w UTC i wymaga, aby sekundy były ciągiem, i wysyła obiekt czasu UTC, natomiast
wyświetla wartość zwracaną w LOKALNEJ strefie czasowej, zwykle wymaga argumentu FixNum, ale sam obiekt Time wciąż jest w UTC, nawet jeśli wyświetlanie nie jest.
Więc mimo że podałem tę samą liczbę całkowitą do obu metod, najwyraźniej mam dwa różne wyniki ze względu na sposób działania
#to_s
metody klasy . Jednak, ponieważ @Eero dwukrotnie musiało mi przypominać:Porównanie równości między dwiema zwracanymi wartościami nadal zwraca wartość true. Ponownie
#==
dzieje się tak, ponieważ wartości są w zasadzie takie same (chociaż różne klasy metoda dba o to za Ciebie), ale#to_s
metoda drukuje drastycznie różne ciągi. Chociaż, jeśli spojrzymy na ciągi, zobaczymy, że rzeczywiście są one w tym samym czasie, tylko drukowane w różnych strefach czasowych.Metoda Wyjaśnienie argumentów
Dokumenty mówią również: „Jeśli podany zostanie argument liczbowy, wynik będzie w czasie lokalnym”. co ma sens, ale było to dla mnie trochę mylące, ponieważ nie podają żadnych przykładów argumentów niecałkowitych w dokumentacji. Tak więc w przypadku niektórych argumentów niecałkowitych:
nie możesz użyć argumentu String, ale możesz użyć argumentu Time do,
Time.at
a zwróci wynik w strefie czasowej argumentu:Benchmarki
Po dyskusji z @AdamEberlin na temat jego odpowiedzi postanowiłem opublikować nieznacznie zmienione testy porównawcze, aby wszystko było jak najbardziej równe. Ponadto, nigdy nie chcę ich ponownie budować, więc jest to tak dobre miejsce, jak każde, aby je uratować.
Time.at (int) .to_datetime ~ 2.8x szybciej
**** edytowane tak, aby nie były całkowicie i całkowicie niepoprawne pod każdym względem ****
**** dodano testy porównawcze ****
źródło
Time.at(1318996912) == DateTime.strptime("1318996912",'%s')
w strefie czasowej innej niż UTC, a zobaczysz!Time.use_zone "Samoa" do Time.at(1318996912) == DateTime.strptime("1318996912",'%s') end
aby sprawdzić, czy czasy są równe, nie ma LOKALNEGO znacznika czasu, aw obu przypadkach uniksowy znacznik czasu jest interpretowany jako UTC.Time.at
przedstawia wynikowy obiekt Time w lokalnej strefie czasowej iDateTime.strptime
przedstawia wynikowy obiekt DateTime w UTC, ale niezależnie od prezentacji są one równe, ponieważ są równoważnym momentem w czasie.Time.at(1318996912) # => 2011-10-19 00:01:52 -0400
wyświetla wartość zwracaną w LOKALNEJ strefie czasowej , nie wydaje się dokładne ... Czy możesz to zweryfikować? Wierzę, że twoje stwierdzenie byłoby prawdziwe tylko wtedy, gdy je użyłeśTime.zone.at(1318996912)
Jedno polecenie konwersji daty i godziny na format uniksowy, a następnie na ciąg znaków
w końcu strftime służy do formatowania daty
Przykład:
źródło
Time.now.utc.to_i
.Informuje o dacie liczby sekund w przyszłości od momentu wykonania kodu.
puts (czas)
zgodnie z obecnym czasem odpowiadam na pytanie, które drukuje
047-05-14 05:16:16 +0000
(1 miliard sekund w przyszłości)lub jeśli chcesz liczyć miliardy sekund od określonego czasu, jest to format
Time.mktime(year, month,date,hours,minutes)
puts („Miałbym 1 miliard sekund na:” + czas)
źródło
Jeśli chcesz tylko datę, możesz zrobić,
Date.strptime(invoice.date.to_s, '%s')
gdzieinvoice.date
przychodzi w postaci an,Fixnum
a następnie przekształcić w aString
.źródło
Time.at(1500923406).to_date.to_s
=>"2017-07-24"