How to Generate a Human Readable Time Range Using Ruby on Rails

How to generate a human readable time range using ruby on rails

If you need something more "precise" than distance_of_time_in_words, you can write something along these lines:

def humanize(secs)
[[60, :seconds], [60, :minutes], [24, :hours], [Float::INFINITY, :days]].map{ |count, name|
if secs > 0
secs, n = secs.divmod(count)

"#{n.to_i} #{name}" unless n.to_i==0
end
}.compact.reverse.join(' ')
end

p humanize 1234
#=>"20 minutes 34 seconds"
p humanize 12345
#=>"3 hours 25 minutes 45 seconds"
p humanize 123456
#=>"1 days 10 hours 17 minutes 36 seconds"
p humanize(Time.now - Time.local(2010,11,5))
#=>"4 days 18 hours 24 minutes 7 seconds"

Oh, one remark on your code:

(self.created_at..self.updated_at).count

is really bad way to get the difference. Use simply:

self.updated_at - self.created_at

How do I display duration in milliseconds as a properly formatted string?

def time_as_str(ms)
secs, ms = ms.divmod(1000)
mins, secs = secs.divmod(60)
hours, mins = mins.divmod(60)
s = "%d.%d.%d.%s" % [hours, mins, secs, ms.zero? ? "0" : ms.to_s.sub(/0*\z/,'')]
if hours > 0
s
elsif mins > 0
s[2..-1]
else
s[4..-1]
end
end

time_as_str(86_400_000) #=> "24.0.0.0"
time_as_str(0) #=> "0.0"
time_as_str(499) #=> "0.499"
time_as_str(60_280) #=> "1.0.28"
time_as_str(360_000) #=> "6.0.0"
time_as_str(1_000_000_200) #=> "277.46.40.2"

See Integer#divmod, an oft-overlooked method.

Suppose

ms = 2_045_670

then

secs, ms    =   ms.divmod(1000)
#=> [2045, 670] (secs #=> 2045, ms #=> 670)
mins, secs = secs.divmod(60)
#=> [34, 5]
hours, mins = mins.divmod(60)
#=> [0, 34]
ms = ms.zero? ? "0" : ms.to_s.sub(/0*\z/,'')
#=> "67" (truncate)
s = "%d.%d.%d.%s" % [hours, mins, secs, ms]
#=> "0.34.5.67"
if hours > 0 # false
"0.34.5.67"
elsif mins > 0 # true
"34.5.67"
else # not evaluated
"5.67"
end
#=> "34.5.67"

How to show time written out?

humantime is one option, but Rails already has time_ago_in_words and distance_of_time_in_words.

Can Ruby print out time difference (duration) readily?

Here's a quick and simple way to implement this. Set predefined measurements for seconds, minutes, hours and days. Then depending on the size of the number, output the appropriate string with the those units. We'll extend Numeric so that you can invoke the method on any numeric class (Fixnum, Bignum, or in your case Float).

class Numeric
def duration
secs = self.to_int
mins = secs / 60
hours = mins / 60
days = hours / 24

if days > 0
"#{days} days and #{hours % 24} hours"
elsif hours > 0
"#{hours} hours and #{mins % 60} minutes"
elsif mins > 0
"#{mins} minutes and #{secs % 60} seconds"
elsif secs >= 0
"#{secs} seconds"
end
end
end

how to get time difference in minutes in rails for two date time fields?

As created_at and updated_at are of type DateTime, this should work.

created = article.created_at
updated = article.updated_at
minutes = ((updated - created) * 24 * 60).to_i

Explanation:

Subtracting two DateTimes returns the elapsed time in days. In the below example e-d will return (28807336643183/28800000000000). So to convert this into minutes, we need to multiply it by 24*60(As the day has 24 hours and each hour has 60 minutes)

Example(tested):

d = DateTime.now
=> Tue, 13 Jun 2017 10:21:59 +0530
2.3.3 :003 > e = DateTime.now + 1.day
=> Wed, 14 Jun 2017 10:22:21 +0530
g = ((e-d) * 24 * 60).to_i
=> 1440

Show duration (in minutes) to hours

distance_of_time_in_words might help you.

You can use it like this:

distance_of_time_in_words(0, 143.minutes)
# => "about 2 hours"

To use an integer / float you'd need to convert to seconds manually:

distance_of_time_in_words(0, 143 * 60)

You could also calculate it like this:

"#{@movie.duration/60}h #{@movie.duration % 60}min"

The division will give you the hours, while the modulo will give you the minutes.


Finally, for the format specified in your question, there's a Gist you can use for the code here.

Ruby on Rails: How do you convert a database entry with attributes inside into a human-readable format?

If your revision column is a String then you can convert any YAML to hash with that:

y = YAML.load(@audit.revisions)
y["kind"] # => "French"

update: I said "hash" above but it will be converted to type that is appropriate for the given YAML. So it can be an array or object. But in your case it will be hash.



Related Topics



Leave a reply



Submit