Time diff in Ruby in terms of minute - ruby-on-rails

I am working on datediff in Ruby. I am making a query to the datebase and I am getting createdDate result in this format:
2016-04-10T19:54:44.000Z.
My task is to check whether difference of createdDate and current time is greater than 30 mins or not. When I create current time in UTC format :
utctime = Time.now.utc
I am getting result like this ;
2016-04-10 19:59:57 UTC
My question is: the createdDate that I get from the database has T and .000Z. in it, it is any easy way to compare them to find 30 mins difference.
Because right now, I am planning to change:
T with space and .000Z. with UTC to make them in the same format.

You can use standard - operator for Time objects:
time_diff = Time.parse('2016-04-10T19:54:44.000Z') - utctime #in seconds
result = (time_diff / 60).abs > 30 #true or false

Related

Converting string time to find difference in time from Time.now ~ Ruby on Rails

I have the time of this format "20:10 PM", I need to find the difference between Time.now with the given time
For example If Time.now says 2022-05-17 18:32:52.133290553 -0700, I need to find the difference between Time.now and "20:10 PM" for same-day today.
I am not able to find any references on Ruby on Rails for that.
Very simple way:
>> Time.now - Time.parse("20:10 PM")
=> 10995.706874
Time.parse will assume today's date if it is not given a date. Returned result is in seconds.
Assuming you always want to compare Time.now with a time from today (i.e 20:30 for today), you could construct a new Time instance for the time you're comparing.
todays_year = Time.now.year
todays_month = Time.now.month
todays_day = Time.now.day
time_to_compare = Time.new(todays_year, todays_month, todays_day, 20, 30) # 20 and 30 represent the dynamic time you want to compare
time_diff = ((Time.now - time_to_compare) / 3600).round(2) # assuming you want to know the difference in hours and rounded to 2 decimal places

Date substraction returning odd value

I am trying to allow the destruction of a record only if this record has been created within the last 30 minutes.
Then I retrieve the created_at value of my record (date2) and check against Time.now (date1) :
date1 = 2016-09-21 19:44:52 +0200
date2 = 2016-09-21 17:23:16 UTC
then I just substract the two :
(date1-date2).minutes.to_i
But the result returned is in the 10s of thousands (something like 97000) and increasing very fast when i refresh..(as Time.now changes) whereas we should only get 141 minutes as per above example values
The .minutes is what makes the thing don't work. Remove it and it should work.
If you want to find the gap in minutes between to date you just have to substract them, divide the result per 60 and round it.
((date1 - date2) / 60).round
Hope it helped, happy ruby coding!
You need to first convert the local time (time1) to UTC time, or UTC time (time2) to local time.
require 'time'
time1 = Time.parse('2016-09-21 19:44:52 +0200')
#=> 2016-09-21 19:44:52 +0200
time2 = Time.parse('2016-09-21 17:23:16 UTC')
#=> 2016-09-21 17:23:16 UTC
(time1.utc - time2)/60
#=> 21.6

Timezone Offset in Angular JS and Rails

Background: I'm building an app with Angular JS as web interface and Rails API. The problem I am having is passing a date from Angular to Rails.
Issue: I have a form with a Date of Birth date field, when a user inputs his DOB say March 1st, 1985, Angular interprets it as 1985-03-01 00:00 +0800 (if you're in Hong Kong or Singapore) and sends a request to Rails. The first thing Rails does with it is to convert it to UTC, which means the datetime is now 1985-02-28 16:00 UTC. Therefore, when the date is saved to the database date column, it becomes Feb 28, 1985.
Solution for now: What I'm doing now is on Angular side, I get the Timezone offset hours and add it to the date, so instead of 1985-03-01 00:00 +0800, it is now 1985-03-01 08:00 +0800. When Rails get it, it converts to 1985-03-01 00:00 UTC and so saves the correct date to db. However, I believe this is a better alternative to tackle this issue.
Thinking about parsing just the date in Rails, yet the params[:dob] I see is already UTC by the time I get it. Would love to know if there is a better practice than my current solution. Thank you for any comment and feedback.
This problem is actually quite common, and stems from two separate but related issues:
The JavaScript Date object is misnamed. It's really a date + time object.
The JavaScript Date object always takes on the characteristics of the time zone for the environment in which it is running in.
For a date-only value like date-of-birth, the best solution to this problem is to not send a full timestamp to your server. Send just the date portion instead.
First, add 12 hours to the time, to use noon instead of midnight. This is to avoid issues with daylight saving time in time zones like Brazil, where the transition occurs right at midnight. (Otherwise, you may run into edge cases where the DOB comes out a day early.)
Then output the date portion of the value, as a string in ISO format (YYYY-MM-DD).
Example:
var dt = // whatever Date object you get from the control
dt.setHours(dt.getHours() + 12); // adjust to noon
var pad = function(n) { return (n < 10 ? '0' : '') + n; }
var dob = dt.getFullYear() + '-' + pad(dt.getMonth()+1) + '-' + pad(dt.getDate());
Another common way to do this is:
var dt = // whatever Date object you get from the control
dt.setHours(dt.getHours() + 12); // adjust to noon
dt.setMinutes(dt.getMinutes() - dt.getTimezoneOffset()); // adjust for the time zone
var dob = dt.toISOString().substring(0,10); // just get the date portion
On the Rails side of things, use a Date object instead of a DateTime. Unlike JavaScript, the Rails Date object is a date-only object - which is perfect for a date-of-birth.

rails group by utc date

I have a time field in table "timestamp without time zone". When record is saved to database, the utc time might be a different day compared to the local time. However, I need to group the records by date. Hence, I am doing something like this:
result = transmissions.joins(:report).where('reports.time::timestamp::date = ?', record.time.to_date)
The problem is if the utc date is on a different date than local time, then that record is not included in result. Any ideas how to get the right result?
And apparently I cannot change the "without time zone" either:
Rails database-specific data type
It says:
"concluded that the default ActiveRecord datetime and timestamp column types in schema migrations cannot be modified to force PostgreSQL to use timestamp with time zone."
So I have no idea how to group by date, as obviously something like this is wrong:
Unit.where(id: 1100).first.reports.order("DATE(time)").group("DATE(time)").count
=> {"2013-12-14"=>19, "2013-12-15"=>5}
That return value is completely wrong. All 25 records should be on 2013-12-14 and 0 records on 2013-12-15.
Assuming your records are timestamped with a particular UTC offset, you can try passing in the start and end times of the date in question in UTC format to your query:
result = transmissions.joins(:report).where('reports.time >= ? AND reports.time < ?', record.time.midnight.utc, (record.time.midnight + 1.day).utc)
Explanation:
midnight is a Rails method on an instance of Time that returns the Time object that represents midnight on the date of the original Time object. Similarly, record.time.midnight + 1.day returns the Time object representing midnight of the following day. Then, converting both Time objects – which are presumably timestamped in a standard UTC offset – to UTC creates a time period representing midnight-to-midnight for the system timezone in UTC format (not midnight in UTC time), which is precisely what you're seeking to query.
How about something like result = transmissions.joins(:report).where('reports.time >= ? AND reports.time <= ?', record.time.beginning_of_day.utc, record.time.end_of_day.utc)
The .utc part may not be necessary.

How does one create objects in the future but ignore yearly/annual TimeZone switches?

I create multiple scheduled objects with different scheduled_on attributes. For example, each object would have a date to land on 4:00pm the first of every month.
Once one of those objects hits a timezone change. The app intelligently configures it an hour ahead or behind so that its relative to its parent's timezone.
The problem is that the app will save an object as 4:00PM (in Pacific Standard) for times that will eventually be displayed as (PDT or an hour ahead or 5:00pm). This would mean that I need it to save an hour off in UTC so that when the time comes about, it will display as 4PM regardless of what timezone we are in.
Whats the best technique for ensuring this in Rails?
I'm going to answer this question by pointing out some good things to know about adding time in Rails in relation to timezone.
When you add time, time is allocated in UTC to stay the same time despite timezone changes :
t = Time.now
-> 2012-08-10 13:17:01 +0200
t + 90.days
-> 2012-11-08 13:17:01 +0100
A DateTime will not do this. A DateTime will go up an hour or down an hour in the same TimeZone it began in :
dt = DateTime.now
=> Fri, 10 Aug 2012 13:16:54 +0200
dt + 90.days
=> Thu, 08 Nov 2012 13:16:54 +0200
But a DateTime is the only way to get the number of days between two dates which you can do by subtracting two DateTimes. This, you can't do with a Time, because when substracting a time, it will not divide by a perfect 24 hours, you'll get an irrational number because of the timezone switch.
This is specific to my issue. But I solved my problem by converting my Time to DateTimes to find the number of days in distance, and then reconverted back to time to find a later time in UTC relative to a TimeZone change :
original_job.to_time + ( new_date.to_datetime - original_job.to_datetime ).to_i.days

Resources