3

我希望在 schema.org 的 ruby​​ on rails 中以 iso8601 格式输出持续时间。我已经知道如何在 iso8601 中输出时间戳。例如 video.created_at.iso8601

我现在要做的是输出以下格式的内容:

<meta itemprop="duration" content="PT1M33S" />

这就是 iso8601 持续时间格式。您可以在http://en.wikipedia.org/wiki/ISO_8601#Durations阅读有关规范的信息

目前我正在使用 strftime 进行黑客攻击,但这并不理想......

Time.at(@video.duration).strftime('PT%MM:%SS')

希望有一个更经典的解决方案。一个足够聪明,可以在需要时处理几个小时等。我依赖 ActiveSupport 等没有问题,因为它将在 Rails 3.2 应用程序中。谢谢!

4

3 回答 3

2

这对我有用,输出是什么:

ruby-1.9.2-head :004 > require 'time'
 => true
ruby-1.9.2-head :005 > Time.at(1000).iso8601
 => "1970-01-01T02:16:40+02:00"
ruby-1.9.2-head :012 > Time.at(1000).getgm.iso8601[10,9]
 => "T00:16:40"
ruby-1.9.2-head :011 > Time.at(60).getgm.iso8601[10,9]
 => "T00:01:00"

通过使用getgm,您可以消除您所在时区的副作用。

编辑:没有意识到你想要 ISO8601 中的持续时间本身——以为你想要一个完全格式化的 ISO8601 时间戳。然后,您可以将这个东西用于您的目标:

https://github.com/arnau/ISO8601

于 2012-03-01T19:05:39.907 回答
2

如果您仍在寻找答案,请查看 ruby​​-duration gem。

于 2012-07-27T03:58:25.800 回答
1
def time_to_iso8601(time)
  # http://www.ostyn.com/standards/scorm/samples/ISOTimeForSCORM.htm
  # P[yY][mM][dD][T[hH][mM][s[.s]S]]

  minute = 60
  hour = minute * 60
  day = hour * 24
  year = day * 365.25
  month = year / 12

  if time.acts_like?(:time)
    time.iso8601
  elsif time.kind_of?(Numeric)
    time = time.to_f
    return "PT0H0M0S" if time == 0

    parts = ["P"]
    parts << "#{(time / year).floor}Y" if time >= year
    parts << "#{(time % year / month).floor}M" if time % year >= month
    parts << "#{(time % month / day).floor}D" if time % month >= day
    time = time % month
    parts << "T" if time % day > 0
    parts << "#{(time % day / hour).floor}H" if time % day >= hour
    parts << "#{(time % hour / minute).floor}M" if time % hour >= minute
    parts << "#{(time % 1 == 0 ? time.to_i : time) % minute}S" if time % minute > 0

    return parts.join
  end
end
于 2014-09-07T16:46:20.607 回答