Как я могу получить количество секунд между двумя DateTimes в Ruby on Rails - PullRequest
61 голосов
/ 20 февраля 2009

У меня есть код, который отслеживает время сотрудников. Он создает счетчик, показывающий сотруднику, как долго они были синхронизированы.

Это текущий код:

  start_time = Time.parse(self.settings.first_clock_in)
  total_seconds = Time.now - start_time
  hours = (total_seconds/ 3600).to_i
  minutes = ((total_seconds % 3600) / 60).to_i
  seconds = ((total_seconds % 3600) % 60).to_i

Это отлично работает. Но поскольку время ограничено диапазоном 1970–2038 гг., Мы пытаемся заменить все время использования датой. Я не могу понять, как получить количество секунд между двумя DateTimes. Вычитание их приводит к Rational, который я не знаю, как интерпретировать, тогда как вычитание Times дает разницу в секундах.

ПРИМЕЧАНИЕ. Начиная с Ruby 1.9.2, жесткий предел времени снят. Однако время оптимизировано для значений между 1823-11-12 и 2116-02-20.

Ответы [ 8 ]

75 голосов
/ 20 февраля 2009

Вычитание двух DateTimes возвращает затраченное время в днях, поэтому вы можете просто сделать:

elapsed_seconds = ((end_time - start_time) * 24 * 60 * 60).to_i
48 голосов
/ 29 мая 2010

Или, более наглядно:

diff = datetime_1 - datetime_2
diff * 1.days # => difference in seconds; requires Ruby on Rails

Обратите внимание, что вы или некоторые другие искатели могли бы действительно искать это:

diff = datetime_1 - datetime_2
Date.day_fraction_to_time(diff) # => [h, m, s, frac_s]
29 голосов
/ 20 февраля 2009

Вы можете преобразовать их в числа с плавающей точкой с помощью to_f, хотя это приведет к обычной потере точности, связанной с числами с плавающей точкой. Если вы просто целые секунды приводите к целому числу, оно не должно быть достаточно большим, чтобы вызывать беспокойство.

Результаты в секундах:

>> end_time.to_f - start_time.to_f
=> 7.39954495429993

>> (end_time.to_f - start_time.to_f).to_i
=> 7

В противном случае, вы можете посмотреть на использование to_formatted_s на объекте DateTime и посмотреть, сможете ли вы уговорить вывод во что-то, что примет класс Decimal, или просто отформатируете его как обычное время Unix в виде строки и вызовите to_i об этом.

9 голосов
/ 22 июня 2016

Другие неправильно полагаются на дроби или вспомогательные функции. Это намного проще, чем это. Сам DateTime является целым числом снизу. Вот способ Ruby:

stop.to_i - start.to_i

Пример:

start = Time.now
 => 2016-06-21 14:55:36 -0700
stop = start + 5.seconds
 => 2016-06-21 14:55:41 -0700
stop.to_i - start.to_i
 => 5
8 голосов
/ 06 ноября 2014

Я использую ruby-2.1.4 и у меня сработало следующее

Time.now - Time.new(2014,11,05,17,30,0)

дал мне разницу во времени в секундах

ссылка: ruby ​​doc

3 голосов
/ 24 февраля 2016

для этого есть метод:

Time.now.minus_with_coercion(10.seconds.ago)

равно 10.

Источник: http://apidock.com/rails/Time/minus_with_coercion

Надеюсь, я помог.

1 голос
/ 29 августа 2016

Определите функцию Ruby следующим образом:

def time_diff(start_time, end_time)
  seconds_diff = (start_time - end_time).to_i.abs

  days = seconds_diff / 86400 
  seconds_diff -= days * 86400

  hours = seconds_diff / 3600  
  seconds_diff -= hours * 3600

  minutes = seconds_diff / 60
  seconds_diff -= minutes * 60

  seconds = seconds_diff

  "#{days} Days #{hours} Hrs #{minutes} Min #{seconds} Sec"
 end

И вызовите эту функцию,

time_diff(Time.now, Time.now-4.days-2.hours-1.minutes-53.seconds)
0 голосов
/ 12 августа 2016

почему бы не использовать встроенную "сек". Вот пример:

t1 = Time.now.sec 

elapsed_t = Time.now.sec - t1

puts "it took me :  #{elapsed_t} seconds to do something that is useful \n"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...