Ruby on rails get hours, minutes, seconds from two dates and times - ruby-on-rails

I need the number of hours, minutes, seconds between two dates and times.I'm able to get the number of days, hours, minutes, seconds but I don't want no.of days instead of it, I need hours, minutes, seconds only enough.
Here my code,
start_time is Wed, 13 Dec 2017 20:35:19 -0800 and end_time is today datetime
def time_diff(end_time, start_time)
diff = end_time - start_time
mm, ss = diff.divmod(60)
hh, mm = mm.divmod(60)
dd, hh = hh.divmod(24)
time = "%d h, %d m, %d s" % [hh, mm, ss]
return time
end
I need output like this "35 h, 29 m, 12 s"
Thanks for your help.

Just out of curiosity, a pure [almost] functional solution, without intermediate local variables:
start_time = DateTime.parse 'Wed, 13 Dec 2017 23:00:00 UTC'
end_time = DateTime.parse 'Wed, 15 Dec 2017 23:30:20 UTC'
sec, min, hrs = [60, 60, 1].
map.
with_object([[[end_time, start_time].
map(&:to_time).
map(&:to_i).
reduce(:-), nil]]) do |div, obj|
obj << obj.last.first.divmod(div)
obj[-2].rotate!
end.
map(&:first).
compact
#⇒ [20, 30, 48]

You've already got the answer - just don't divide by 24!

If the start_time and end_time are DateTime value you can use the following
difference = end_time - start_time
hours = (difference * 24).to_i
minutes = (difference * 24 * 60).to_i
seconds = (difference * 24 * 60 * 60).to_i

Related

how to calculate (date - duration) in google sheets

How can I reduce a specific duration from a date?
for example -
the base date and time to reduce from
15/05/2018 02:00:00
the duration to reduce -
03:00:00 hours
the expected output -
14/05/2018 23:00:00
=A1-3/24-5/(24*60)-55/(24*60*60)
where
A1 = 15/05/2018 02:00:00
3 = the number of hours to reduce
5 = minutes
55 = seconds
If you have time in format: 03:05:55, the formula is simple:
=A1 - A2
where
A1 = 15/05/2018 02:00:00
A2 = 03:05:55

Ruby: Calculate time difference between 2 times

I want to calculate the difference between 2 times.
start_time: 22:00 (Rails interprets this as 2015-12-31 22:00:00 +0100)
second_time: 02:00 (Rails interprets this as 2015-12-31 02:00:00 +0100). The second time is 4 hours later, so in the next day. Is there a way to calculate this difference?
I can not simply do this: second_time - first_time, because this gives me a difference of 22 hours instead of 4 hours.
Edit:
Some background information:
A job is starting at 22:00 and ending the next day at 02:00. Because i fill in the form of this job only times, this times for the above 2 values are 2015-12-31 22:00:00 +0100 and 2015-12-31 02:00:00 +0100. I don't want the user to fill in the time including the date. The real difference between the times should be 4 hours.
So what i actually want is calculate the difference between 22:00 and 02:00 (in the next day).
I don't understand why you think it should return 4 hours or why it does return 22 hours. 20 hours would be correct for your example:
require 'time'
a = Time.parse('2015-12-31 22:00:00 +0100')
b = Time.parse('2015-12-31 02:00:00 +0100')
a - b
#=> 72000.0 # difference in seconds
(a - b) / 3600
#=> 20.0 # difference in hours
Update: It seems like you are dealing only with the time portion and not with the actual date. And I assume the maximum difference you will have to deal with is 24 hours:
def time_difference(time_a, time_b)
difference = time_b - time_a
if difference > 0
difference
else
24 * 3600 + difference
end
end
a = Time.parse('2015-12-31 22:00:00 +0100')
b = Time.parse('2015-12-31 02:00:00 +0100')
time_difference(a, b) / 3600
# => 4 # hours
a = Time.parse('2015-12-31 02:00:00 +0100')
b = Time.parse('2015-12-31 22:00:00 +0100')
time_difference(a, b) / 3600
# => 20 # hours
Old question but I did a nice method to deal with it:
def time(start,ending)
if start != ending
medidas=["year","month","day","hour","minute","second"]
array=[1970,1,1,0,0,0]
text = ""
Time.at(ending-start).utc.to_a.take(6).reverse.each_with_index do |k,i|
text = "#{text} #{I18n.translate medidas[i].to_sym, count: k-array[i]}"
end
text = text.strip.squish
pos = text.rindex(" ",(text.rindex(" ")-1))
unless pos.nil?
text = text.insert(pos," and")
end
text = text.strip.squish #This shouldn't be needed but just in case
else
"0 seconds"
end
end
Then in config/locales/en.yml I added:
en:
año:
zero: ''
one: '1 year'
other: '%{count} years'
mes:
zero: ''
one: '1 month'
other: '%{count} months'
dia:
zero: ''
one: '1 day'
other: '%{count} days'
hora:
zero: ''
one: '1 hour'
other: '%{count} hours'
minuto:
zero: ''
one: '1 minute'
other: '%{count} minutes'
segundo:
zero: ''
one: '1 second'
other: '%{count} seconds'
So for example when you call:
start = Time.now
ending = start + (60*60)
time(start,ending)
=> "1 hour"
ending = start + (60*60*28)
time(start,ending)
=> "1 day and 4 hours"
ending = start + (53*60*5874)
time(start,ending)
=> "7 months 4 days 4 hours and 42 minutes"
Hope it's useful
I'd write it thusly (before adding data checks), in an attempt to make it self-documenting:
require 'time'
DT_FMT = '%Y-%m-%d %H:%M:%S %z'
SECONDS_PER_DAY = 24*60*60
def hours_elapsed(start_str, finish_str)
start = DateTime.strptime(start_str, DT_FMT).to_time
finish = DateTime.strptime(finish_str, DT_FMT).to_time
finish = same_time_tomorrow(finish) if finish < start
(finish-start)/3600
end
def same_time_tomorrow(time)
time + SECONDS_PER_DAY
end
hours_elapsed '2015-12-31 22:00:00 +0100',
'2015-12-31 02:00:00 +0100'
#=> 4.0
hours_elapsed '2015-12-31 02:00:00 +0100',
'2015-12-31 22:00:00 +0100'
#=> 20.0
It may be better for the arguments of hours_elapsed to be strings containing hours and minutes only, in which case we might rename the method as well. time_elapsed("18:00", "2:30") is an example of how this method might be invoked.
MINUTES_PER_DAY = 24*60
def time_elapsed(start_str, finish_str)
start_mins = time_str_to_minutes(start_str)
finish_mins = time_str_to_minutes(finish_str)
finish_mins += MINUTES_PER_DAY if
finish_mins < start_mins
(finish_mins-start_mins).divmod(60)
end
def time_str_to_minutes(str)
hrs, mins = str.split(':').map(&:to_i)
60 * hrs + mins
end
time_elapsed("8:00", "17:30")
#=> [9, 30]
time_elapsed("18:00", "2:30")
#=> [8, 30]

Subtracting Time.now from End_time (UTC) gives me a float (hhmmss.xx). How do I format it to HH:MM so that I can use it for a countdown timer?

I have an end_time that I would like to create a timer for end_time.utc - Time.now. However, when I subtract the value, I get a float like 23510.29642 which I found to represent hours, minutes,seconds followed by a period and milliseconds.
end_time
=> Wed, 04 Jun 2014 19:00:00 UTC +00:00
end_time.utc - Time.now
=> -24614.329399
How do I format the float so that I get -2:46 without manually parsing the string?
Difference between two Time objects returns number of seconds between two times.
e = Time.parse("Wed, 04 Jun 2014 19:00:00 UTC +00:00")
diff = e - Time.parse("Wed, 04 Jun 2014 21:49:00 UTC +00:00")
hours = (diff / 3600).to_i
minutes = (diff / 60).to_i % 60 # if e < Time.now then minutes = (diff / 60).to_i % 60 - 60
seconds = diff.to_i % 60 # same as minutes
puts hours # -2
puts minutes # -49
puts seconds # 0

How to format time durations in Groovy?

I need to show time elapsed. I have the dates in following format.
Date1 = Thu May 23 10:10:10 EDT 2013
Date2 = Tue May 21 10:10:10 EDT 2013
I currently did TimeDuration duration=TimeCategory.minus(now,LaunchTime)
And my output shows something like 2 days, 23 minutes, 25.154 seconds
What I want to show instead of 2 days, 23 minutes, 25.154 seconds is something like 48:23:25(in hours and minutes).
You can do something like this to create a new TimeDuration with the days turned into hours:
import groovy.time.TimeDuration
import groovy.time.TimeCategory
date1 = Date.parseToStringDate( 'Thu May 23 10:10:10 EDT 2013' )
date2 = Date.parseToStringDate( 'Tue May 21 12:14:10 EDT 2013' )
// Normalize method to return a new TimeDuration
TimeDuration normalize( TimeDuration tc ) {
new TimeDuration( ( tc.days != 0 ? tc.days * 24 : 0 ) + tc.hours,
tc.minutes, tc.seconds, tc.millis )
}
// Then use the category to subtract the dates, and call normalize
TimeDuration normalized = use( groovy.time.TimeCategory ) {
normalize( date1 - date2 )
}
println normalized

Subtract dates in Ruby and get the difference in minutes

how do i subtract two different UTC dates in Ruby and then get the difference in minutes?
Thanks
If you subtract two Date or DateTime objects, the result is a Rational representing the number of days between them. What you need is:
a = Date.new(2009, 10, 13) - Date.new(2009, 10, 11)
(a * 24 * 60).to_i # 2880 minutes
or
a = DateTime.new(2009, 10, 13, 12, 0, 0) - DateTime.new(2009, 10, 11, 0, 0, 0)
(a * 24 * 60).to_i # 3600 minutes
(time1 - time2) / 60
If the time objects are string, Time.parse(time) them first
https://rubygems.org/gems/time_difference - Time Difference gem for Ruby
start_time = Time.new(2013,1)
end_time = Time.new(2014,1)
TimeDifference.between(start_time, end_time).in_minutes
Let's say you have two dates task_signed_in and task_signed_out for a simple #user object. We could do like this:
(#user.task_signed_out.to_datetime - #user.task_signed_in.to_datetime).to_i
This will give you result in days. Multiply by 24 you will get result in hours and again multiply by 60 you will result in minutes and so on.
This is the most up to date solution tested in ruby 2.3.x and above.

Resources