如何使用ruby on rails生成人类可读的时间范围

csa*_*anz 27 ruby time ruby-on-rails

我正在尝试找到生成以下输出的最佳方法

<name> job took 30 seconds
<name> job took 1 minute and 20 seconds
<name> job took 30 minutes and 1 second
<name> job took 3 hours and 2 minutes
Run Code Online (Sandbox Code Playgroud)

我启动了这段代码

def time_range_details
  time = (self.created_at..self.updated_at).count
  sync_time = case time 
    when 0..60 then "#{time} secs"       
    else "#{time/60} minunte(s) and #{time-min*60} seconds"
  end
end
Run Code Online (Sandbox Code Playgroud)

有没有更有效的方法来做到这一点.对于一些非常简单的东西,似乎有很多冗余代码.

另一个用途是:

<title> was posted 20 seconds ago
<title> was posted 2 hours ago
Run Code Online (Sandbox Code Playgroud)

这个代码是类似的,但我使用Time.now:

def time_since_posted
  time = (self.created_at..Time.now).count
  ...
  ...
end
Run Code Online (Sandbox Code Playgroud)

Mla*_*vić 60

如果你需要更"精确"的东西distance_of_time_in_words,你可以写下这些内容:

def humanize secs
  [[60, :seconds], [60, :minutes], [24, :hours], [Float::INFINITY, :days]].map{ |count, name|
    if secs > 0
      secs, n = secs.divmod(count)

      "#{n.to_i} #{name}" unless n.to_i==0
    end
  }.compact.reverse.join(' ')
end

p humanize 1234
#=>"20 minutes 34 seconds"
p humanize 12345
#=>"3 hours 25 minutes 45 seconds"
p humanize 123456
#=>"1 days 10 hours 17 minutes 36 seconds"
p humanize(Time.now - Time.local(2010,11,5))
#=>"4 days 18 hours 24 minutes 7 seconds"
Run Code Online (Sandbox Code Playgroud)

哦,你的代码有一句话:

(self.created_at..self.updated_at).count
Run Code Online (Sandbox Code Playgroud)

非常糟糕的方式来获得差异.使用简单:

self.updated_at - self.created_at
Run Code Online (Sandbox Code Playgroud)

  • @csanz:`.count`在这种情况下迭代两个时间戳之间的每秒数组并计算它们.好像你会通过实际计算50到100之间的所有数字来计算表达式"100-50"的结果. (3认同)
  • 我更喜欢DateHelper方法.如果您打算将其转换为英语,那么您可能不希望将天数和秒数结合起来.这是一种人工精确度. (2认同)
  • 这段代码很棒,但是如果超过1000天(86_400_000秒),它将无法正常工作。`humanize(86_400_001)=&gt;“ 0天0小时0分1秒”是错误的。可以通过将数组的最后一个元素更新为`[Float :: INFINITY,:days]`来修复此错误。 (2认同)

Dou*_*g R 27

有两种方法DateHelper可能会给你你想要的东西:

  1. time_ago_in_words

    time_ago_in_words( 1234.seconds.from_now ) #=> "21 minutes"
    
    time_ago_in_words( 12345.seconds.ago )     #=> "about 3 hours"
    
    Run Code Online (Sandbox Code Playgroud)
  2. distance_of_time_in_words

    distance_of_time_in_words( Time.now, 1234.seconds.from_now ) #=> "21 minutes"
    
    distance_of_time_in_words( Time.now, 12345.seconds.ago )     #=> "about 3 hours"
    
    Run Code Online (Sandbox Code Playgroud)


小智 7

chronic_duration将数字时间解析为可读,反之亦然