How to format the output of a time::span to a string? e.g. "3h24m12s"

For now, I have to use like following:

ic(1.20.0-dev):004> time_span.total_seconds
=> 20.22026478

def formatted_duration(duration : Float64?) : String
        return "" if duration.nil?

        total_milliseconds = (duration * 1000).round.to_i64
        total_seconds = total_milliseconds // 1000

        hours = total_seconds // 3600
        minutes = (total_seconds % 3600) // 60
        seconds = total_seconds % 60
        milliseconds = total_milliseconds % 1000

        if hours > 0
          "#{hours}h#{minutes}m#{seconds}s"
        elsif minutes > 0
          "#{minutes}m#{seconds}s"
        elsif seconds > 0
          milliseconds > 0 ? "#{seconds}.#{milliseconds.to_s.rjust(3, '0')}s" : "#{seconds}s"
        else
          "#{milliseconds}ms"
        end
      end

formatted_duration(time_span.total_seconds)
1 Like

That’s basically what I do, too.

I think it mostly depends on your use case, though, so I don’t know if there’s a good general-purpose solution to this. If you’re trying to make it human-readable, you have to determine how much precision you want to show. Like, maybe “2h31m14.5s” is more precision than you’re looking for when “2h” would be close enough. Maybe we could add a Time::Span#to_s(format : String) overload like Time#to_s has.

I wrote up a quick proof of concept here:

1 Like

Ha, That’s exactly what I thought initially too, why isn’t there something like Time.to_s(format)?

Maybe we should add it into STDLIB, anyway, no lose, and Time/Time::Span #to_s use same pattern, if both share (partly) same code base is more good.

I have code to format and parse these types of time spans in my library Geode: Commands because of errors git fsck defaults to HEAD. If you.

3 Likes

I wrote a Time::Span String Converter shard that might be of some help.

2 Likes

@straight-shoota Are we accept a PR for add this feature to std-lib ?

I can try analyzing and consolidating all the implementations provided by the users above and submit a PR.

I believe this topic needs a bit more design exploration.

As you may notice, the different solutions mentioned here use very different implementations:

These are very different strategies aiming at different use cases.

1 Like