如何获取Ruby on Rails中两个DateTime之间的秒数


70

我有可以对员工进行时间跟踪的代码。它创建了一个计数器来显示员工需要等待多长时间。

这是当前代码:

  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。我不知道如何获取两个DateTime之间的秒数。减去它们会生成一个我不知道如何解释的有理数,而减去Times则会得到以秒为单位的差异。

注意:从Ruby 1.9.2开始,时间的硬性限制已被删除。但是,“时间”已针对1823-11-12和2116-02-20之间的值进行了优化。

Answers:


87

减去两个DateTimes将返回以天为单位的经过时间,因此您可以执行以下操作:

elapsed_seconds = ((end_time - start_time) * 24 * 60 * 60).to_i

啊,我知道它会在几天之内返回它,但我不知道这还包括一天的零头。谢谢。
Tilendor

4
如果出现Le秒(en.wikipedia.org/wiki/Leap_second),这将无法正常工作。
Rok Kralj 2013年

38
只是对可能对此感到困惑的任何人的注释。是的,减去2 DateTimes将返回以天为单位的经过时间。但是,在Rails中,您迁移的模型属性datetime实际上可能是an ActiveSupport::TimeWithZone,然后减去其中两个返回的经过时间(以秒为单位)
evanrmurphy

3
我正在使用它并得到一个分数,日期时间相隔2秒,分别是15和13,但是我得到1.939s而不是2s,.to_i被截断为1秒。
ckarbass

48

或者,更容易理解的是:

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]

这似乎不适用于我(created_at和updated_at)。我的两个数字是2016-08-07 20:33:54.8635682016-08-07 20:33:54.788684,但差是6469.9776。Posgres说这些字段是“没有时区的时间戳”,如果有区别的话。
CHawk '16

1
NoMethodError:1:Fixnum的未定义方法“天”
android.weasel

1
请注意,.days是一种rails方法,没有它就无法在ruby中使用。
sakurashinken

31

您可以使用将它们转换为浮点数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_sDateTime对象上的使用情况,看看是否可以将输出哄骗到Decimal该类将接受的内容中,或者只是将其格式化为纯Unix时间的字符串并调用to_i它。


感谢Luke,.to_f转换很棒!它独立于Date类工作:可以是DateTime或ActiveSupport :: TimeWithZone。
yaru 2015年

1
NoMethodError:#<DateTime:0x00000002240840>的未定义方法`to_f'–
jameshfisher

18

其他人错误地依赖小数或辅助函数。比这简单得多。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



1

定义这样的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)

-2

为什么不使用内置的“ sec”。这是一个例子:

t1 = Time.now.sec 

elapsed_t = Time.now.sec - t1

puts "it took me :  #{elapsed_t} seconds to do something that is useful \n"

sec方法将返回每次的秒组成部分,不包括分钟,小时等。相反,可以使用例如to_i来处理自epoc以来的总秒数。
雷·迈尔斯

.sec显示当前时间的秒数,因此不是正确的选择
Navid Farjad
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.