【问题标题】:Ruby: Convert time to seconds?Ruby:将时间转换为秒?
【发布时间】:2011-04-18 23:18:10
【问题描述】:

如何将 10:30 这样的时间转换为秒?是否有某种内置的 Ruby 函数来处理这个问题?

基本上试图计算从午夜 (00:00) 到一天中特定时间(例如 10:30 或 18:45)的秒数。

【问题讨论】:

    标签: ruby time


    【解决方案1】:

    可以使用DateTime#parse将字符串转为DateTime对象,然后将小时乘以3600,分钟乘以60得到秒数:

    require 'date'
    
    # DateTime.parse throws ArgumentError if it can't parse the string
    if dt = DateTime.parse("10:30") rescue false 
      seconds = dt.hour * 3600 + dt.min * 60 #=> 37800
    end
    

    正如 jleedev 在 cmets 中指出的,如果您有 ActiveSupport,您也可以使用 Time#seconds_since_midnight

    require 'active_support'
    Time.parse("10:30").seconds_since_midnight #=> 37800.0
    

    【讨论】:

    • 这似乎需要主动支持。
    • 另外,还有一个seconds_since_midnight 方法。
    • 关于 ArgumentError...有没有办法将数字转换为时间?所以说输入只是“8”......我想转换为“8:00”
    • @jleedev 更新为使用DateTime#parse
    • 为了扭转这一点,看看stackoverflow.com/questions/2310197/…
    【解决方案2】:

    又一个实现:

    Time.now.to_i - Date.today.to_time.to_i # seconds since midnight
    

    【讨论】:

      【解决方案3】:

      内置的 time 库扩展了 Time 类来解析字符串,所以你可以使用它。它们最终表示为自 UNIX 纪元以来的秒数,因此转换为整数和减法应该得到你想要的。

      require 'time'
      m = Time.parse('00:00')
      t = Time.parse('10:30')
      
      (t.to_i - m.to_i)
      => 37800
      

      ActiveSupport 中还有一些糖可以处理这些类型的事情。

      【讨论】:

      • 注意。当应用于 DateTime 对象时,这将返回一个带有当前日期的字符串,如果在午夜进行计算,这可能会或可能不会混淆问题。
      • 有没有办法将 10:30 解析为 10 分 30 秒?
      【解决方案4】:

      或许还有更简洁的方式,但是:

      t = Time.parse("18:35")
      s = t.hour * 60 * 60 + t.min * 60 + t.sec
      

      会成功的。

      【讨论】:

        【解决方案5】:

        你可以简单地使用

        Time.parse("10:30").seconds_since_midnight
        

        【讨论】:

          【解决方案6】:

          我非常喜欢这些答案,尤其是Teddy's,因为它很整洁。

          有一点需要注意。泰迪的回答给出了当前区域的第二天,我无法将Date.today.to_time 转换为UTC。我最终得到了这个解决方法:

          Time.now.to_i % 86400
          

          这是基于 Time.now.to_i 给出 自 Unix 纪元以来的秒数,无论您当前的时区如何,它始终为 1970-01-01T00:00:00Z。而且一天也有 86400 秒。因此,此解决方案将始终为您提供自上次 UTC 午夜以来的秒数。

          【讨论】:

            【解决方案7】:
            require 'time'
            
            def seconds_since_midnight(time)
              Time.parse(time).hour * 3600 + Time.parse(time).min * 60 + Time.parse(time).sec
            end
            
            puts seconds_since_midnight("18:46")
            

            所有很棒的答案,这就是我最终使用的。

            【讨论】:

              【解决方案8】:

              在纯红宝石中,最快的是时间部分的总和:

              require 'benchmark'
              require 'time'
              
              Benchmark.bm do |x|
                x.report('date') { 100_000.times { Time.now.to_i - Date.today.to_time.to_i } }
                x.report('parse') { 100_000.times { Time.now.to_i - Time.parse('00:00').to_i } }
                x.report('sum') { 100_000.times { Time.now.hour * 3600 + Time.now.min * 60 + Time.now.sec } }
              end
              
                     user     system      total        real
              date  0.820000   0.000000   0.820000 (  0.822578)
              parse  1.510000   0.000000   1.510000 (  1.516117)
              sum  0.270000   0.000000   0.270000 (  0.268540)
              

              所以,如果需要,这里有一个考虑时区的方法

              def seconds_since_midnight(time: Time.now, utc: true)
                time = time.utc if utc
                time.hour * 3600 + time.min * 60 + time.sec
              end
              

              【讨论】:

                猜你喜欢
                • 2011-04-27
                • 2018-03-15
                • 2011-06-05
                • 2011-08-28
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多