Add DateTime offset in seconds - ruby-on-rails

I have a DateTime in UTC, and would like add an offset which is provided in seconds
#json parsed - utc offset in seconds - turned into integer
#utc_offset = result["UTCOffsetMillis"].to_i
#json parsed - utc date
start_date_string = result["startDate"].split("-")
start_date = DateTime.new(start_date_string[0].to_i, start_date_string[1].to_i,start_date_string[2].to_i)
How do I add this offset in seconds to start_date??
Rails 3.2.3
Ruby 1.9.2p320

To add an offset in seconds to a DateTime you can use:
DateTime.new(2012, 10, 31) + 5.seconds
#=> Wed, 31 Oct 2012 00:00:05 +0000
To change the timezone, I'd use Time instead of DateTime:
Time.new(2012, 10, 31, 0, 0, 0, 3600).localtime
#=> 2014-10-31 00:00:00 +0100
3600 is the offset from UTC in seconds.

Related

In Rails, how to convert time zone into an integer

I have time and time zone, what I need is I just want to convert like this Wed, 11 Dec 2019 19:00:00 +0530 and then I need to convert like this 1576071000.
So for I tried like this
time = "19"
hour = "00"
time_zone = "IST"
e = DateTime.now.change({hour: time, minute: hour})
I get the exact output, but I need to convert with timezone. that means something like this
DateTime.now.change({hour: time, minute: hour}).time_zone('IST')
credit to #engineersmnky
hour = 19
minute = 0
time_zone = 'Chennai'
e = Time.zone.now.change({hour: hour, minute: minute}).in_time_zone(time_zone).to_i
You need to convert it to UTC:
DateTime.now.change({hour: time, minute: hour}).time_zone('IST').utc
Or if you are in Rails 4 or above you can use in_time_zone:
DateTime.now.change({hour: time, minute: hour}).in_time_zone('IST').utc

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

Transforming date + time in a TimeStamp Object

I'm having some trouble with making a timestamp from a date and a time
What i'm trying to do:
date = "2016 2 21"
time = "03:00 UTC"
output = "Thu, 21 Feb 2016 03:00:00 UTC +00:00"
I'm getting the date from a form_for:
f.date_field(:date_first)
But I'm not sure of how should I pick up the time.
To give you a headstart:
dt = "2016-2-21"
time = "03:00 UTC"
dtime = DateTime.parse(dt + 'T' + time)
output = dtime.rfc2822
and the result is:
#=> "Sun, 21 Feb 2016 03:00:00 +0000"
Maybe you could do something like this
strftime("%d.%m.%Y. %H:%M:%S")
and also get your locale yml file from here
https://github.com/svenfuchs/rails-i18n/tree/master/rails/locale

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

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