How to output days as hours in Ruby on Rails? - ruby-on-rails

In my Ruby on Rails application I have a constant like this:
TIME = 3.days
Is there a way to output this value in hours?
# => 72
Thanks for any help.

Ruby or Rails has no direct method for this but if you google you can find a lot of way to do this.you can try followings:
3.days/1.hour
also take a look at Is there any method in Rails to convert minutes as integer to days, months, etc

> 3.days / 3600
=> 72
Not very intuitive, I know.

TIME = 3.days
=> 259200
TIME/3600
=> 72
We have to covert it in hours (60 * 60 = 3600) :P

in_hours (Rails 6.1+)
Rails 6.1 introduces new ActiveSupport::Duration conversion methods like in_seconds, in_minutes, in_hours, in_days, in_weeks, in_months, and in_years.
As a result, now, your problem can be solved as simple as:
3.days.in_hours
# => 72.0
Here is a link to the corresponding PR.

Related

Show duration (in minutes) to hours

I want to display the duration of a movie. Right now the movie.duration is shown in minutes (integer)
%b Duration: #{ #movie.duration } # 134 mins
Does rails have a time helper to show this is in a more human-readable way? Something like this:
Duration: 2h 23min
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.
Try Following
def formatted_duration(total_minute)
hours = total_minute / 60
minutes = (total_minute) % 60
"#{ hours }h #{ minutes }min"
end

How to convert X months to Y days in Rails in one step?

I have a configuration value stored as 3.months, and another value returning from a calculation as 7.days.
I need to find their difference. What is the easiest & Railsiest way to normalise them so that I can subtract 7.days from 3.months? I can turn .months into days by using .to_i & multiplying by seconds-in-a-day, but it feels pretty long-winded to have to calculate from months to seconds to days like this:
x = (3.months.to_i/86400).days
=> 90 days
x - 7.days
=> 83 days
Is there a snappier way?
If you want to keep each term with units of time I would recommend this:
(3.months - 7.days)/1.day
I feel like its the cleanest and easiest for another dev to realize what you are trying to describe.
Not sure it's any better but:
end_date = Date.today.advance(months: 3) - 7.days
(end_date - Date.today).to_i #=> 83
I'f I understand correctly, you can subtract them one from another like so:
(3.months - 7.days)/86400 #=> 83
Both months and days methods return an integer of seconds.

convert with rails time helpers

Rails offers helpers like 24.hours, 1.minute etc. How can I get the number of minutes in 1.hour?
One option, if you want to stick with the 1.hour style language, is to divide by a single "minute":
1.hour / 1.minute
# => 60
5.hours / 1.minute
# => 300
n.minutes or n.hours are numerically kept in the form of seconds so to convert in minutes try this
hour_in_minutes = 1.hour/60
Try
1.hours/1.minute
At the end, 1.hours, etc. is just a Fixnum
1.hour.minutes will return 60 minutes.

grouping and displaying by dates

I have a rails application and I want to display messages (Message) to the user based on the time the messages have arrived
every message (Message) has a property called created_at
for example
-- 20 minutes ago
-----message1
-----message2
-- 1 hour ago
-----message3
-----message4
-----message5
-- 2 days ago
-----message6
and so on and so forth.
how can I do this using rails?
I am using rails 3 b.t.w
You basically have two options. The first is to use the built-in Rails helper time_ago_in_words:
# in your views
<%= time_ago_in_words(message.created_at) %>
You can read more about this helper in the Rails documentation.
The downside with this is that it only works in views, and it might not be the entirely correct format. If that's the case, you can always define your own helper in an initializer. Here's a method I coded up for an old app, which you should be able to modify to suit your requirements:
class ActiveSupport::TimeWithZone
def how_long_ago
seconds = (Time.now - self)
# Keep adding days, weeks, months, years if necessary--same principle should apply
if seconds > 3600
(seconds / 3600).to_i.to_s + "h " + (seconds % 3600 / 60).to_i.to_s + "m"
elsif seconds > 60
(seconds / 60).to_i.to_s + "m " + (seconds % 60).to_i.to_s + "s"
else
seconds.to_i.to_s + "s"
end
end
end
Message.first.created_at.how_long_ago # => 3m 52s
To group the data based on this, you can use the group_by method on the messages array.
You can set default scope in your Message model:
default_scope order('messages.created_at DESC')
I found an answer on RailsCasts which is perfect for my needs
http://railscasts.com/episodes/29-group-by-month

How to evaluate a date difference in years, months and days (ruby)?

I have to make a simple difference between two dates:
Date.parse("2009-06-20") - Date.today
This gives me the difference of the dates in days.
Anyone know a way to easily convert that to the following format:
The event occurred X years, Y months and Z days ago
Thank you.
Found the answer here:
More precise distance_of_time_in_words
with this gem:
https://github.com/radar/dotiw
You may be looking for distance_of_times_in_words
There is a RubyGem which returns Time difference in a hash like {:year => 0, :month => 0,...}
The link is : https://rubygems.org/gems/time_diff
This is an example for difference in days, hours, seconds. Add the fields that you need.
def calculate_difference
minutes = (Date.parse("2009-06-20") - Date.today).to_i / 60
days = minutes / (24*60)
minutes -= days * 24*60
hours = minutes / 60
minutes -= hours * 60
"#{days}d#{hours}h#{minutes}m"
end
I find these generic date differences useful in many cases:
time_a = Time.zone.parse('2020-05-30')
time_b = Time.zone.parse('2010-01-18')
time_diff = {
years: time_a.year - time_b.year,
months: time_a.month - time_b.month,
days: time_a.day - time_b.day,
}
=> {:years=>10, :months=>4, :days=>12}
I don't know of any standard, correct way to do this. As odd as it may seem the standard Ruby library has a Date class but no DateSpan functionality. Rails has a solution but it feels somewhat of a pain for me to require this whole mammoth for such a trivial task.

Resources