Output Ruby duration in iso8601

I'm looking to output duration in iso8601 format in ruby on rails for schema.org. I already know how to output the timestamp in iso8601. e.g. video.created_at.iso8601

What I'm looking to do now is output something in the format of:

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

That's the iso8601 duration format. You can read about the spec at http://en.wikipedia.org/wiki/ISO_8601#Durations

Currently I'm hacking in a strftime, but that's not ideal...

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

Would appreciate a classier solution. And one smart enough to handle hours, etc when needed. I have no problem relying on ActiveSupport, etc as it'll be in a Rails 3.2 app. Thanks!

Answers


If you're still looking for an answer to this, check out the ruby-duration gem.


Here is what worked for me and what was the output:

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"

By using getgm, you eliminate side effects from your time zone.

EDIT: Didn't realize you wanted the duration itself in ISO8601 -- thought you wanted a piece off a fully formatted ISO8601 timestamp. You could use this thingy for your goal then:

https://github.com/arnau/ISO8601


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

Need Your Help

Get current IST time in php

php

I am using the following code to get current IST time. But it only gives the system time. I changed my system time due to some reason. So i get only system time instead of current time.

How to check if data is empty or whitespace only in PHP

php html whitespace removing-whitespace

I have an input field that needs a username. The scenario is, how can i prevent user from providing whitespace or whitespaces in the that field? I already added required in the input field so i can