Як отримати поточний час як 13-значне ціле число в Ruby?


88

У мене є ця jQueryфункція, яка повертає поточний час як кількість мілісекунд з епохи (1 січня 1970 р.):

time = new Date().getTime();

Чи є спосіб зробити те саме в Ruby?

Зараз я використовую Ruby's, Time.now.to_iякий чудово працює, але повертає 10-значне ціле число (кількість секунд)

Як я можу змусити його відображати кількість мілісекунд, як у jQuery?


5
Це не "функція jQuery", це просто ECMAScript (javascript). Можливо, саме це спонукало до -1, хоча й трохи жорстко.
RobG

Відповіді:


151
require 'date'

p DateTime.now.strftime('%s') # "1384526946" (seconds)
p DateTime.now.strftime('%Q') # "1384526946523" (milliseconds)

31
Примітка для користувачів Rails: strftimeметод, передбачений, ActiveSupport::TimeWithZoneне включає специфікатори %sта %Q. DateTimeСпочатку потрібно перетворити на звичайний Ruby , використовуючи to_datetimeметод.
Lonnon Foster

6
@LonnonFoster Тепер це працює (щойно перевірено в консолі Rails).
Нікола Стоякович

Привіт, як я можу зробити те саме, але поки що не, а скоріше з поля дати?
Томер


100

Javascript gettime()повертає кількість мілісекунд з епохи.

Ruby's Time.now.to_iдасть вам кількість секунд з епохи. Якщо змінити це на Time.now.to_f, ви все одно отримуєте секунди, але з дробовим компонентом. Просто помножте це на 1000 і у вас будуть мілісекунди. Потім використовуйте #to_iдля перетворення його в ціле число. І ви закінчуєте:

(Time.now.to_f * 1000).to_i

Велике спасибі за пояснення! Все ще новачок у всій цій справі ... Не знаю, яку відповідь позначити як правильну насправді ...
Tintin81

1
Тільки для отримання додаткової інформації, Time.nowнадходить від Ruby, оскільки Time.currentпоходить від Rails. Таким чином , Time.currentпідтверджується Rails часовому поясу додатків і Time.nowвикористовує часовий пояс сервера. З мого досвіду, завжди використовуйте Time.currentу своїй програмі Rails для узгодженості часових поясів
vutran

1
Ні, вам взагалі не слід Time.currentтут користуватися, побудова займає більше часу, а оскільки ви відразу ж перетворюєте його на часову мітку unix, ви взагалі не дбаєте про узгодженість часового поясу. (Мітки часу Unix завжди стосуються UTC). Отже, хоча те, що ви кажете, відповідає дійсності в 99% випадків, але це з точки зору ефективності падає на останні 1%.
The Pellmeister

1
Це мій кращий підхід. Одне, що я люблю робити, - це збільшити клас Time, щоб додати :epochметод: class Time def epoch (self.to_f * 1000) .to_i end end
Matt Welke

1
це підробляє мілісекунди
брауліобо

31

(Time.now.to_f * 1000).to_i повинні робити те саме.


1
@brauliobo що таке підроблені мілісекунди?
Ерік Ротофф,

1
@brauliobo Це не так, оскільки to_fвключає мілісекунди як десяткову.
CashIsClay

20

За допомогою strftimeви можете отримати кількість секунд і додати дробові мілісекунди (або менші одиниці, якщо потрібно):

2.2.2 :001 > t = Time.new
 => 2015-06-02 12:16:56 -0700 
2.2.2 :002 > t.strftime('%s%3N')
 => "1433272616888" 

Зверніть увагу, що це не округлюється, а усікає, як ви можете бачити за допомогою to_fмікросекунд або якщо ви перейдете до мікросекунд:

2.2.2 :003 > t.to_f
 => 1433272616.888615
2.2.2 :004 > t.usec
 => 888615 

і to_f/ to_iрішення має ту саму проблему:

2.2.2 :009 > (t.to_f * 1000).to_i
 => 1433272616888

так що якщо ви дійсно дбаєте про мілісекунди точності, краще ставка може бути to_fз round:

2.2.2 :010 > (t.to_f * 1000).round
 => 1433272616889

Тим НЕ менше, як і зазначено в документації , «IEEE 754 подвійний мало точні , щоб представити число наносекунд , починаючи з епохи», так що якщо ви на самому справі на самому ділі все одно, розглянемо to_rзамість to_f-

2.2.2 :011 > (t.to_r * 1000).round
 => 1433272616889 

- хоча, якщо ви округлюєте лише до мілісекунд, ви, мабуть, добре.


18

Будь обережний, не плутайся. Той факт, що Рубі підтримує ідею дробових секунд як плаваючої, насправді не робить її числом із плаваючою точкою. Я зіткнувся з цим, коли робив порівняння часу відмітки часу Wireshark в Python ... обчислення часу в pcap-ng просто не працювали. Лише коли я обробив дві частини (цілі секунди та цілі наносекунди), оскільки обидва цілі числа, я зміг отримати правильні числа.

Це тому, що числа з плаваючою комою мають проблеми з точністю . Справді, короткий шматок Ruby покаже вам, що to_f не дорівнює, скажімо, 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

Застереження програміста. У вас можуть бути 3 значні цифри, але факт залишається фактом: числа з плаваючою комою на комп’ютерах - це наближення. Наносекундні лічильники на сучасних комп’ютерах є цілими числами.


Краща реакція. Дякую. .strftime("%9N")Також можна використовувати формат директиви . ruby-doc.org/core-2.3.1/Time.html#method-i-strftime
rplaurindo

13

Отримайте об'єкт Time за допомогою Time.nowвиклику #to_iповертає мітку часу Unix (секунди від епохи). #to_fдає дробові секунди, які ви можете використовувати для отримання мілісекунд від епохи:

Time.now.to_f * 1000

3
це підробляє мілісекунди
брауліобо

0

Ціле число (1e6 * Time.now.to_f) повертає Bignum, який може утримувати мілісекунди

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