Ответ 1
require 'date'
p DateTime.now.strftime('%s') # "1384526946" (seconds)
p DateTime.now.strftime('%Q') # "1384526946523" (milliseconds)
У меня есть эта функция jQuery
, которая возвращает текущее время как число миллисекунд с эпохи (1 января 1970 года):
time = new Date().getTime();
Есть ли способ сделать то же самое в Ruby?
В настоящее время я использую Ruby Time.now.to_i
, который отлично работает, но возвращает 10-значное целое число (количество секунд)
Как я могу заставить его отображать число миллисекунд, как в jQuery
?
require 'date'
p DateTime.now.strftime('%s') # "1384526946" (seconds)
p DateTime.now.strftime('%Q') # "1384526946523" (milliseconds)
Javascript gettime()
возвращает число миллисекунд с эпохи.
Ruby Time.now.to_i
даст вам количество секунд с эпохи. Если вы измените это на Time.now.to_f
, вы все равно получите секунды, но с дробным компонентом. Просто умножьте это на 1000, и у вас миллисекунды. Затем используйте #to_i
, чтобы преобразовать его в целое число. И вы получите:
(Time.now.to_f * 1000).to_i
(Time.now.to_f * 1000).to_i
должен делать то же самое.
Получите Time объект Time.now
, вызов #to_i
возвращает отметку времени Unix (в секундах от эпохи). #to_f
дает дробные секунды, которые вы можете использовать для получения миллисекунд с эпохи:
Time.now.to_f * 1000
Будьте осторожны, не путайте. Тот факт, что Ruby поддерживает идею дробных секунд как float, фактически не делает его числом с плавающей запятой. У меня возникли проблемы с этим, когда я делал сравнения времени времени 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
Программист Caveat. Вы можете быть в безопасности до 3 значащих цифр, но факт остается фактом: цифры с плавающей запятой на компьютерах являются приблизительными. Наносекундные счетчики на современных компьютерах являются целыми числами.
Используя 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
- хотя, если вы только округляете до миллисекунды, вы, вероятно, хорошо.
Признак Integer (1e6 * Time.now.to_f) возвращает Bignum, который может удерживать миллисекунды