【问题标题】:How do you do relative time in Rails?你如何在 Rails 中处理相对时间?
【发布时间】:2008-10-12 17:29:56
【问题描述】:

我正在编写一个 Rails 应用程序,但似乎找不到如何计算相对时间,即如果给定某个 Time 类,它可以计算“30 秒前”或“2 天前”或者更长超过一个月“2008 年 9 月 1 日”等。

【问题讨论】:

  • 'calculate' 似乎是错误的词,你的意思是'output'吗?

标签: ruby-on-rails ruby


【解决方案1】:

听起来您正在寻找来自 ActiveSupport 的 time_ago_in_words 方法(或 distance_of_time_in_words)。像这样称呼它:

<%= time_ago_in_words(timestamp) %>

【讨论】:

  • 提示 ruby​​ 新手如何在 irb 中运行它?我运行: require 'active_support' 然后尝试 'time_ago_in_words(Time.now)' 但找不到该函数。
  • @cboettig 它不是ActiveSupport 的一部分,它在ActionView::Helpers::DateHelper 中定义。
  • 如果您在 Rails 控制台中,则不需要“active_support”。有一个名为helper 的控制台方法,您可以调用和访问这些方法。 helper.time_ago_in_words(timestamp)
  • 仅供参考,如果你想在 irb 或纯 Ruby 中使用它,只需执行以下操作:require 'active_support/core_ext' 首先,然后你就可以使用 7.days.ago 和其他类似的结构了。跨度>
  • 太棒了!我刚来这里期待一些示例代码并找到了这个。我喜欢 ruby​​ 和 rails
【解决方案2】:

我已经写了这个,但必须检查提到的现有方法,看看它们是否更好。

module PrettyDate
  def to_pretty
    a = (Time.now-self).to_i

    case a
      when 0 then 'just now'
      when 1 then 'a second ago'
      when 2..59 then a.to_s+' seconds ago' 
      when 60..119 then 'a minute ago' #120 = 2 minutes
      when 120..3540 then (a/60).to_i.to_s+' minutes ago'
      when 3541..7100 then 'an hour ago' # 3600 = 1 hour
      when 7101..82800 then ((a+99)/3600).to_i.to_s+' hours ago' 
      when 82801..172000 then 'a day ago' # 86400 = 1 day
      when 172001..518400 then ((a+800)/(60*60*24)).to_i.to_s+' days ago'
      when 518400..1036800 then 'a week ago'
      else ((a+180000)/(60*60*24*7)).to_i.to_s+' weeks ago'
    end
  end
end

Time.send :include, PrettyDate

【讨论】:

  • 嗯,我首先阅读了 ruby​​,并且 ruby​​ 没有开箱即用的 ActiveSupport。所以我认为这篇文章更红宝石。但是在实际问题中提到了rails。
  • Rails 是一个 web 框架,底层语言是 ruby​​。因此,在 rails 问题上获得一些 ruby​​ 代码是很正常的。即使标准 ruby​​ 不包含 ActiveRecord,也仅通过“gem install activerecord”命令即可支持。
  • 您可以将case语句中的最后一个return-line放在else下,并删除所有returns。
  • 有人能说出为什么会有+99+800+180000吗?
  • +99 因为“一小时前”的结尾在 7100 处结束,比两小时短了 100 秒。同样,+800,因为 172000 比两天短 800 秒(172800 秒),以此类推。
【解决方案3】:

只是为了澄清 Andrew Marshall 使用 time_ago_in_words 的解决方案
(适用于 Rails 3.0 和 Rails 4.0)

如果你在视野中

<%= time_ago_in_words(Date.today - 1) %>

如果你在控制器中

include ActionView::Helpers::DateHelper
def index
  @sexy_date = time_ago_in_words(Date.today - 1)
end

控制器默认没有导入模块ActionView::Helpers::DateHelper

注意将助手导入控制器不是“轨道方式”。助手用于帮助视图。 time_ago_in_words 方法被确定为 MVC 三元组中的 view 实体。 (我不同意,但在罗马时......)

【讨论】:

    【解决方案4】:

    怎么样

    30.seconds.ago
    2.days.ago
    

    或者你正在拍摄的其他东西?

    【讨论】:

    • 这与问题所说的相反。
    【解决方案5】:

    您可以使用算术运算符来计算相对时间。

    Time.now - 2.days 
    

    2天前会给你。

    【讨论】:

    • 你知道 2.days.ago 吗?
    • 是否有`Time.now + 2.days' 的简写方法?
    • @NixNinja: 2.days.since2.days.from_now
    • 这与问题所问的相反。 time_ago_in_words 是问题的答案。
    【解决方案6】:

    这样的事情会起作用。

    def relative_time(start_time)
      diff_seconds = Time.now - start_time
      case diff_seconds
        when 0 .. 59
          puts "#{diff_seconds} seconds ago"
        when 60 .. (3600-1)
          puts "#{diff_seconds/60} minutes ago"
        when 3600 .. (3600*24-1)
          puts "#{diff_seconds/3600} hours ago"
        when (3600*24) .. (3600*24*30) 
          puts "#{diff_seconds/(3600*24)} days ago"
        else
          puts start_time.strftime("%m/%d/%Y")
      end
    end
    

    【讨论】:

    • 这本质上是对 distance_of_time_in_words 帮助器的重新实现:api.rubyonrails.com/classes/ActionView/Helpers/…
    • 这意味着你不应该使用它,你应该使用内置的
    • 这对我来说似乎很好。它允许您自定义其余的字符串。即“3 秒前”与“3 秒前”
    • #{diff_seconds/360} 应该是 #{diff_seconds/3600}。我已经编辑过了。
    【解决方案7】:

    因为这里的大多数答案建议 time_ago_in_words

    而不是使用:

    <%= time_ago_in_words(comment.created_at) %>
    

    在 Rails 中,更喜欢:

    <abbr class="timeago" title="<%= comment.created_at.getutc.iso8601 %>">
      <%= comment.created_at.to_s %>
    </abbr>
    

    连同一个jQuery库http://timeago.yarp.com/,带有代码:

    $("abbr.timeago").timeago();
    

    主要优势:缓存

    http://rails-bestpractices.com/posts/2012/02/10/not-use-time_ago_in_words/

    【讨论】:

    • 其实是time_ago_in_words不是时间S
    【解决方案8】:

    看看这里的实例方法:

    http://apidock.com/rails/Time

    这有一些有用的方法,例如昨天、明天、begin_of_week、ago 等。

    例子:

    Time.now.yesterday
    Time.now.ago(2.days).end_of_day
    Time.now.next_month.beginning_of_month
    

    【讨论】:

      【解决方案9】:

      如果你正在构建一个 Rails 应用程序,你应该使用

      Time.zone.now
      Time.zone.today
      Time.zone.yesterday
      

      这会在您配置 Rails 应用程序的时区中为您提供时间或日期。

      例如,如果您将应用程序配置为使用 UTC,那么Time.zone.now 将始终采用 UTC 时间(例如,它不会受到英国夏令时变化的影响)。

      计算相对时间很容易,例如

      Time.zone.now - 10.minute
      Time.zone.today.days_ago(5)
      

      【讨论】:

        【解决方案10】:

        我为 Rails ActiveRecord 对象编写了一个 gem。该示例使用 created_at,但它也适用于 updated_at 或具有 ActiveSupport::TimeWithZone 类的任何内容。

        只需 gem install 并在您的 TimeWithZone 实例上调用“漂亮”方法。

        https://github.com/brettshollenberger/hublot

        【讨论】:

          【解决方案11】:

          另一种方法是从后端卸载一些逻辑并让浏览器通过使用 Javascript 插件来完成这项工作,例如:

          jQuery time ago 或其Rails Gem adaptation

          【讨论】:

            猜你喜欢
            • 2010-11-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-12-03
            • 1970-01-01
            • 2010-09-18
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多