Subtract dates in Ruby and get the difference in minutes - ruby-on-rails

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.

Related

How can I find the average of 3 date in Ruby on rails or Ruby?

How can I find the average of 3 date in Ruby on rails or Ruby ? like bellow.
(Date1 + Date2 + Date3)/3
If you convert the dates to integers with .to_i you can do the average exactly as you suggested. Then use .at to get back to a datetime.
d1 = Time.now
=> 2022-03-16 11:07:12 -0700
d2 = Time.now - 10000
=> 2022-03-16 08:20:32 -0700
d3 = Time.now - 30000
=> 2022-03-16 02:47:12 -0700
Time.at((d1.to_i + d2.to_i + d3.to_i)/3)
=> 2022-03-16 07:24:58 -0700
first_date = Date.today.strftime("%Y%m%d").to_i
second_date = Date.tomorrow.strftime("%Y%m%d").to_i
third_date = Date.yesterday.strftime("%Y%m%d").to_i
average_date = (first_date + second_date + third_date) / 3
Date.parse(average_date.to_s) OR Time.at(average_date)
If you are working with Date objects (Not Time nor DateTime) you can easily calculate the middle date between 3 (or even more dates if you add them to the array).
Imagine you have your dates in an array:
dates = [Date.today, 1.day.ago, 10.days.ago]
difference = dates.max - dates.min
average_date = dates.min + difference/2
Basically, we're getting the days difference between the higher date value and the minimum date value, then adding half that difference to the smallest date, and there you have the average date between the 3, the date in the middle won't change anything so it's not being used with this approach.

How can I find the average date of n-number dates. n number of date coming as array in rails [duplicate]

How can I find the average of 3 date in Ruby on rails or Ruby ? like bellow.
(Date1 + Date2 + Date3)/3
If you convert the dates to integers with .to_i you can do the average exactly as you suggested. Then use .at to get back to a datetime.
d1 = Time.now
=> 2022-03-16 11:07:12 -0700
d2 = Time.now - 10000
=> 2022-03-16 08:20:32 -0700
d3 = Time.now - 30000
=> 2022-03-16 02:47:12 -0700
Time.at((d1.to_i + d2.to_i + d3.to_i)/3)
=> 2022-03-16 07:24:58 -0700
first_date = Date.today.strftime("%Y%m%d").to_i
second_date = Date.tomorrow.strftime("%Y%m%d").to_i
third_date = Date.yesterday.strftime("%Y%m%d").to_i
average_date = (first_date + second_date + third_date) / 3
Date.parse(average_date.to_s) OR Time.at(average_date)
If you are working with Date objects (Not Time nor DateTime) you can easily calculate the middle date between 3 (or even more dates if you add them to the array).
Imagine you have your dates in an array:
dates = [Date.today, 1.day.ago, 10.days.ago]
difference = dates.max - dates.min
average_date = dates.min + difference/2
Basically, we're getting the days difference between the higher date value and the minimum date value, then adding half that difference to the smallest date, and there you have the average date between the 3, the date in the middle won't change anything so it's not being used with this approach.

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

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

Ruby Program time conversion

The task is to Write a method that will take in a number of minutes, and returns a string that formats the number into hours:minutes.
here's what I have so far:
def time_conversion(minutes)
minutes = (minutes / 60) % 60
hours = minutes / (60 * 60)
format(" %02d:%02d ", hours, minutes)
return format
end
it's not working out for me
Try this
def time_conversion(time)
minutes = time % 60
hours = time / 60
minutes = (minutes < 10)? "0" + minutes.to_s : minutes.to_s
return hours.to_s + ":" + minutes
end
Using division in Ruby returns a whole number, lowered to the previous number. Using modulus returns the remainder after division.
Ruby's Numeric#divmod is exactly what you want here. It returns both the quotient and remainder of a division operation, so e.g. 66.divmod(60) returns [ 1, 6 ]. Combined with sprintf (or String#%, it makes for an extremely simple solution:
def time_conversion(minutes)
"%02d:%02d" % minutes.divmod(60)
end
puts time_conversion(192)
# => 03:12
Well try
h = minutes/60
M = minutes%60

rounding a Rails DateTime to the nearest 15 minute interval

I need to round a DateTime and also a Time to the nearest 15 minute interval. My thought is to zero out the seconds and the milliseconds (do those exist in a DateTime or Time?) and maybe even nanoseconds? And then divide the number of minutes by 15, round that, then multiply the result by 15 and set that to be the minutes:
# zero out the seconds
time -= time.sec.seconds
# zero out the milliseconds (does that exist?)
# zero out the nanoseconds (less likely this exists)
minutes_should_be = (time.min / 15.to_f).round * 15
time += (minutes_should_be - time.min).minutes
So I guess my question is if there is a better way to do this and if milliseconds and nanoseconds exist in a DateTime or Time? There is a nsec method for nanoseconds, but I think that's the total nanoseconds since epoch.
The following should do the trick:
##
# rounds a Time or DateTime to the neares 15 minutes
def round_to_15_minutes(t)
rounded = Time.at((t.to_time.to_i / 900.0).round * 900)
t.is_a?(DateTime) ? rounded.to_datetime : rounded
end
The function converts the input to a Time object, which can be converted to the seconds since the epoch with to_i (this automatically strips nano-/milliseconds). Then we divide by 15 minutes (900 seconds) and round the resulting float. This automatically rounds the time to the nearest 15 minutes. Now, we just need to multiply the result by 15 minutes and convert it to a (date)time again.
Example values:
round_to_15_minutes Time.new(2013, 9, 13, 0, 7, 0, "+02:00")
#=> 2013-09-13 00:00:00 +0200
round_to_15_minutes Time.new(2013, 9, 13, 0, 8, 0, "+02:00")
#=> 2013-09-13 00:15:00 +0200
round_to_15_minutes Time.new(2013, 9, 13, 0, 22, 29, "+02:00")
#=> 2013-09-13 00:15:00 +0200
round_to_15_minutes Time.new(2013, 9, 13, 0, 22, 30, "+02:00")
#=> 2013-09-13 00:30:00 +0200
round_to_15_minutes DateTime.now
#=> #<DateTime: 2013-09-13T01:00:00+02:00 ((2456548j,82800s,0n),+7200s,2299161j)>
A generic rounding solution for DateTime, based on Tessi's answer:
class DateTime
def round(granularity=1.hour)
Time.at((self.to_time.to_i/granularity).round * granularity).to_datetime
end
end
Example usage:
DateTime.now.round 15.minutes
> Fri, 15 May 2015 11:15:00 +0100
I think this will work
def nearest15 minutes
((minutes / 60.0 * 4).round / 4.0 * 60).to_i
end
The idea, is
get your minutes in terms hours (decimal)
round to the nearest quarter
convert back to minutes
Some sample output
10.times do
n = [*1..200].sample
puts "%d => %d" % [n, nearest15(n)]
end
Output
85 => 90
179 => 180
54 => 60
137 => 135
104 => 105
55 => 60
183 => 180
184 => 180
46 => 45
92 => 90

Resources