Mam tę jQuery
funkcję, która zwraca bieżący czas jako liczbę milisekund od epoki (1 stycznia 1970):
time = new Date().getTime();
Czy jest sposób, aby zrobić to samo w Rubim?
W tej chwili używam Rubiego, Time.now.to_i
który działa świetnie, ale zwraca 10-cyfrową liczbę całkowitą (liczbę sekund)
Jak mogę sprawić, aby wyświetlał liczbę milisekund, tak jak w jQuery
?
Odpowiedzi:
require 'date' p DateTime.now.strftime('%s') # "1384526946" (seconds) p DateTime.now.strftime('%Q') # "1384526946523" (milliseconds)
źródło
strftime
metoda dostarczona przezActiveSupport::TimeWithZone
nie zawiera specyfikatorów%s
i%Q
.DateTime
Najpierw musisz przekonwertować na zwykły Ruby , używając tejto_datetime
metody.JavaScript
gettime()
zwraca liczbę milisekund od epoki.Ruby
Time.now.to_i
poda liczbę sekund od epoki. Jeśli zmienisz to naTime.now.to_f
, nadal otrzymasz sekundy, ale z ułamkowym składnikiem. Po prostu pomnóż to przez 1000 i masz milisekundy. Następnie użyj,#to_i
aby przekonwertować go na liczbę całkowitą. Otrzymujesz:(Time.now.to_f * 1000).to_i
źródło
Time.now
pochodzi od Rubiego, ponieważTime.current
pochodzi z Railsów. Tak więcTime.current
jest to potwierdzane przez strefę czasową aplikacji Railsów iTime.now
używa strefy czasowej serwera. Z mojego doświadczenia, zawsze używaćTime.current
od aplikacji Rails dla spójności czasowejTime.current
tutaj, konstruowanie zajmuje więcej czasu, a ponieważ natychmiast konwertujesz go na uniksowy znacznik czasu, nie przejmujesz się w ogóle spójnością strefy czasowej. (Znaczniki czasu systemu Unix zawsze odnoszą się do czasu UTC). Tak więc, chociaż to, co mówisz, jest prawdą w 99% przypadków, ten pod względem wydajności przypada na ostatni 1%.:epoch
metodę: class Time def epoch (self.to_f * 1000) .to_i end end(Time.now.to_f * 1000).to_i
powinien zrobić to samo.źródło
to_f
zawiera milisekundy jako ułamek dziesiętny.Używając
strftime
, możesz uzyskać liczbę sekund i dołączyć ułamkowe milisekundy (lub mniejsze jednostki, jeśli to konieczne):2.2.2 :001 > t = Time.new => 2015-06-02 12:16:56 -0700 2.2.2 :002 > t.strftime('%s%3N') => "1433272616888"
Zwróć jednak uwagę, że to nie zaokrągla, obcina, jak widać z
to_f
lub jeśli wychodzisz do mikrosekund:2.2.2 :003 > t.to_f => 1433272616.888615 2.2.2 :004 > t.usec => 888615
a
to_f
/to_i
rozwiązanie ma ten sam problem:2.2.2 :009 > (t.to_f * 1000).to_i => 1433272616888
więc jeśli naprawdę dbają o milisekundy dokładność, lepszy zakład może być
to_f
zround
:2.2.2 :010 > (t.to_f * 1000).round => 1433272616889
To powiedziawszy, jak zauważono w dokumentach , „IEEE 754 double nie jest wystarczająco dokładny, aby przedstawić liczbę nanosekund od Epoki”, więc jeśli naprawdę cię to obchodzi, rozważ
to_r
zamiastto_f
-2.2.2 :011 > (t.to_r * 1000).round => 1433272616889
- chociaż jeśli zaokrąglasz tylko do milisekund, prawdopodobnie jesteś w porządku.
źródło
Uważaj, nie daj się zmylić. Fakt, że Ruby wspiera ideę ułamków sekund jako liczby zmiennoprzecinkowej, w rzeczywistości nie sprawia, że jest to liczba zmiennoprzecinkowa. Wpadłem z tym w kłopoty, kiedy robiłem porównania czasu znaczników czasu Wireshark w Pythonie ... obliczenia czasu w pcap-ng po prostu nie działały. Dopiero gdy potraktowałem dwie części (całkowite sekundy i całkowite nanosekundy) jako obie liczby całkowite, byłem w stanie uzyskać odpowiednie liczby.
Dzieje się tak, ponieważ liczby zmiennoprzecinkowe mają problemy z dokładnością . Rzeczywiście, krótki fragment Rubiego pokaże ci, że to_f nie równa się, powiedzmy, nsec:
irb(main):019:0> t=Time.now => 2015-04-10 16:41:35 -0500 irb(main):020:0> puts "#{t.to_f}; #{t.nsec}" 1428702095.1435847; 143584844
Caveat Programmer. Możesz być bezpieczny do 3 cyfr znaczących, ale fakt pozostaje: Liczby zmiennoprzecinkowe na komputerach są przybliżeniami. Liczniki nanosekund na nowoczesnych komputerach to liczby całkowite.
źródło
.strftime("%9N")
również użyć formatu dyrektywy . ruby-doc.org/core-2.3.1/Time.html#method-i-strftimePobierz obiekt Time za pomocą
Time.now
, wywołanie#to_i
zwraca uniksowy znacznik czasu (sekundy od epoki).#to_f
daje ułamkowe sekundy, których możesz użyć, aby uzyskać milisekundy z epoki:Time.now.to_f * 1000
źródło
Typecast Integer (1e6 * Time.now.to_f) zwraca Bignum, który może pomieścić milisekundy
źródło