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
Ruby Read CSV File as Utf-8 And/Or Convert Ascii-8Bit Encoding to Utf-8
Differencebetween Integer and Fixnum
Ruby: Dynamically Generate Attribute_Accessor
Actionview::Template::Error (Incompatible Character Encodings: Utf-8 and Ascii-8Bit)
Is There Goto Statement in Ruby
How to Sort an Array of Hashes by a Value in the Hash
Bundler Cannot Install Any Gems Without Sudo
Parsing String to Add to Url-Encoded Url
How to Find the Unique Elements in an Array in Ruby
Looping Through Bits in an Integer, Ruby
Using Ruby Convert Numbers to Words
Rails Gem Rails3-Jquery-Autocomplete How to Scope by User
Block Syntax Difference Causes "Localjumperror: No Block Given (Yield)"
How to Pass Parameter on 'Vagrant Up' and Have It in the Scope of Vagrantfile