Una respuesta inspirada en la de Lev Lukomsky que aprovecha ActiveSupport :: Duration y maneja milisegundos (útil para comparar el código)
# duration in ms modulus number of ms in one second
milliseconds = duration.in_milliseconds % 1.second.in_milliseconds
# duration in seconds modulus number of seconds in one minute
seconds = (duration / 1.second) % (1.minute / 1.second)
# duration in minutes modulus number of minutes in one hour
minutes = (duration / 1.minute) % (1.hour / 1.minute)
# duration in hours modulus number of hours in one day
hours = (duration / 1.hour) % (1.day / 1.hour)
format("%02d:%02d:%02d:%03d", hours, minutes, seconds, milliseconds) #=> "12:05:00:001"
Por supuesto, puede extender esto fácilmente con días, meses, años, etc. utilizando métodos relacionados de ActiveSupport y repitiendo la misma estructura.
Tenga en cuenta que para duraciones demasiado largas, esto puede ser inexacto, ya que la duración de 1 mes no se fija en el número de días, y no estoy seguro de cómo AS: Duration trata eso.