【问题标题】:Calculating the difference between durations with milliseconds in Ruby在 Ruby 中计算持续时间与毫秒之间的差异
【发布时间】:2011-12-14 15:54:40
【问题描述】:

TL;DR:我需要得到HH:MM:SS.msHH:MM:SS.ms之间的区别HH:MM:SS:ms


我需要什么:

这是一个棘手的问题。我正在尝试计算两个时间戳之间的差异,如下所示:

In: 00:00:10.520
Out: 00:00:23.720

应该交付:

Diff: 00:00:13.200

我想我会将时间解析为实际的 Time 对象并使用其中的差异。这在前一种情况下效果很好,并返回00:0:13.200

什么不起作用:

但是,对于某些人来说,这不起作用,因为 Ruby 使用 usec 而不是 msec

In: 00:2:22.760
Out: 00:2:31.520
Diff: 00:0:8.999760

显然,区别应该是00:00:8:760 而不是00:00:8.999760我真的很想tdiff.usec.to_s.gsub('999','') ......


到目前为止我的代码:

这是我目前的代码(这些是从“0:00:10:520”等输入字符串中解析出来的)。

tin_first, tin_second = ins.split(".")
tin_hours, tin_minutes, tin_seconds = tin_first.split(":")
tin_usec = tin_second * 1000
tin = Time.gm(0, 1, 1, tin_hours, tin_minutes, tin_seconds, tin_usec)

tout 也是如此。那么:

tdiff = Time.at(tout-tin)

对于输出,我使用:

"00:#{tdiff.min}:#{tdiff.sec}.#{tdiff.usec}"

有没有更快的方法来做到这一点?请记住,我只是想要两次之间的差异。我错过了什么?

我目前正在使用 Ruby 1.9.3p6。

【问题讨论】:

    标签: ruby time datetime-conversion


    【解决方案1】:

    使用Time

    require 'time' # Needed for Time.parse
    
    def time_diff(time1_str, time2_str)
      t = Time.at( Time.parse(time2_str) - Time.parse(time1_str) )
      (t - t.gmt_offset).strftime("%H:%M:%S.%L")
    end
    
    out_time = "00:00:24.240"
    in_time  = "00:00:14.520"
    
    p time_diff(in_time, out_time)
    #=> "00:00:09.720"
    

    这是一个不依赖Time的解决方案:

    def slhck_diff( t1, t2 )
      ms_to_time( time_as_ms(t2) - time_as_ms(t1) )
    end
    
    # Converts "00:2:22.760" to 142760
    def time_as_ms( time_str )
      re = /(\d+):(\d+):(\d+)(?:\.(\d+))?/
      parts = time_str.match(re).to_a.map(&:to_i)
      parts[4]+(parts[3]+(parts[2]+parts[1]*60)*60)*1000
    end
    
    # Converts 142760 to "00:02:22.760"
    def ms_to_time(ms)
      m = ms.floor / 60000
      "%02i:%02i:%06.3f" % [ m/60, m%60, ms/1000.0 % 60 ]
    end
    
    t1 = "00:00:10.520"
    t2 = "01:00:23.720"
    p slhck_diff(t1,t2)
    #=> "01:00:13.200"
    
    t1 = "00:2:22.760"
    t2 = "00:2:31.520"
    p slhck_diff(t1,t2)
    #=> "00:00:08.760"
    

    【讨论】:

    • parts = time_str.split(/[:\.]/).map(&:to_i) ? (零件则有 4 个元素)
    • @steenslag 更简单,当然。出于某种原因,我在split 之前使用了正则表达式。 :) 更好的是,我本可以在 : 上拆分并使用 to_f(以及稍微不同的数学来加起来)。
    【解决方案2】:

    我认为以下方法可行:

    out_time = "00:00:24.240"
    in_time = "00:00:14.520"
    diff = Time.parse(out_time) - Time.parse(in_time)
    Time.at(diff).strftime("%H:%M:%S.%L")
    # => "01:00:09.720"
    

    确实打印了一个小时的01,我不太明白。

    同时,我使用了:

    Time.at(diff).strftime("00:%M:%S.%L")
    # => "00:00:09.720"
    

    当然,任何做得更好的答案都会得到赞成或接受。

    【讨论】:

    • 问题是因为您将 diff 视为 GMT,然后在您的本地时区显示时间。结果我的电脑显示"17:00:09.720"。请参阅我的答案以了解如何避免这种情况。
    【解决方案3】:
    in_time = "00:02:22.760"
    out_time = "00:02:31.520"
    diff = (Time.parse(out_time) - Time.parse(in_time))*1000
    puts diff
    

    输出:

    8760.0 millliseconds
    

    Time.parse(out_time) - Time.parse(in_time)seconds 中给出结果,因此乘以1000 以转换为milliseconds

    【讨论】:

    • 那行不通——至少对我来说是这样。你试过了吗?我收到invalid date 错误。例如,测试Date.strptime("00:2:22.760","%H:%M:%S.%L") 会抛出此错误(Ruby 1.9.3p6)
    • 更新了代码。它工作正常,我已经在我的机器上测试过
    猜你喜欢
    • 2016-08-14
    • 2012-07-22
    • 1970-01-01
    • 2018-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-23
    相关资源
    最近更新 更多