17

i want to calculate time difference in minutes between two date_time fields.like created_at and updated_at kind of fields. i want the result like this updated_at - created_at = some minutes.

these times are present in time zone of INDIA. how can i do that in rails?

created = article.created_at
updated = article.updated_at

minutes = updated - created
John
  • 1,273
  • 3
  • 27
  • 61
  • Could you clear some things here. What do you really meant by `date_time` fields? The fields of datatype `DateTime`? – Pavan Jun 14 '17 at 04:44

5 Answers5

43

This solution works for ActiveRecord models using TimeWithZone classes for created_at and updated_at.

created = article.created_at
updated = article.updated_at

minutes = (updated - created) / 1.minutes
Doug
  • 14,387
  • 17
  • 74
  • 104
  • This will work if `created_at`/`updated_at` are instances of `Time`. Which they aren't, as claimed in Pavan's answer. I'm wondering, can it depend on an application setting or rails version or something? – Sergio Tulentsev Jun 13 '17 at 05:44
  • This is clean and more intuitive since it indicates that the resulting units will be `minutes`. Thanks. – Joshua Pinter Oct 13 '22 at 14:55
19

As created_at and updated_at are of type DateTime, this should work.

created = article.created_at
updated = article.updated_at
minutes = ((updated - created) * 24 * 60).to_i

Explanation:

Subtracting two DateTimes returns the elapsed time in days. In the below example e-d will return (28807336643183/28800000000000). So to convert this into minutes, we need to multiply it by 24*60(As the day has 24 hours and each hour has 60 minutes)

Example(tested):

d = DateTime.now
 => Tue, 13 Jun 2017 10:21:59 +0530 
2.3.3 :003 > e = DateTime.now + 1.day
 => Wed, 14 Jun 2017 10:22:21 +0530
g = ((e-d) * 24 * 60).to_i
 => 1440
Sergio Tulentsev
  • 226,338
  • 43
  • 373
  • 367
Pavan
  • 33,316
  • 7
  • 50
  • 76
  • 6
    Sorry but how does this work? `updated - created` will give you a time difference in seconds, which should be divided by 60 to give you minutes. I have no idea why you're multiplying these seconds by the number of minutes in a day... – toxaq Aug 25 '16 at 21:44
  • 5
    This answer is incorrect. I've put the correct answer [below](http://stackoverflow.com/questions/30953115/how-to-get-time-difference-in-minutes-in-rails-for-two-date-time-fields/39254215#39254215) – Doug Aug 31 '16 at 16:02
  • Careful @Doug I got downvoted for questioning this answer and providing a correct solution. Seems to be some gaming going on here... 5 upvotes for an utterly and completely wrong answer? Can't be explained logically... – toxaq Sep 02 '16 at 09:07
  • @toxaq Did you read the question? `created_at` and `updated_at` are of type **DateTime** not **Time**. So this is the correct answer and your answer wrong! – Pavan Jun 13 '17 at 05:01
  • @Doug Did you read the question? `created_at` and `updated_at` are of type **DateTime** not **Time**. So this is the correct answer and your answer wrong! – Pavan Jun 13 '17 at 05:02
  • @toxaq And nothing is going on here! I got upvotes because its a **correct answer**. Its simple as that! – Pavan Jun 13 '17 at 07:53
  • 1
    @pavan I queried it first with no reply. It's incredibly astute of you to noticed that created_at and updated_at have gone against the convention of Rails and used Datetime fields instead of the standard timestamp. Kudos to you! I think that deserves some extra explanation considering a number of people have made that exact query and provided the solution as per convention. Again, well done you for spotting the devil in the detail. – toxaq Jun 13 '17 at 09:17
  • 1
    @pavan haha, never not friends! My initial query was an echo in the dark :P Can you add some clarification around timestamp vs datetime for others like Doug and myself that got thoroughly confused? I've deleted my answer already. – toxaq Jun 13 '17 at 09:24
  • @toxaq Sure! I'll add that! – Pavan Jun 13 '17 at 09:25
  • @toxaq You meant *time vs datetime*? – Pavan Jun 13 '17 at 09:32
  • @pavan well this adds more confusion really. Created_at and updated_at are added using `t.timestamps` in a Rails migration. In Postgres at least, this creates a `timestamp without time zone` field and if you check the class of a model.created_at/updated_at it will be an `ActiveSupport::TimeWithZone`, which is Time like. So any clarification would be good around class vs column and the convention. – toxaq Jun 13 '17 at 09:50
  • @toxaq I'll clear it up for sure. Give me some time :) – Pavan Jun 13 '17 at 09:56
  • @toxaq `:datetime` and `:timestamp` will default to *DATETIME* while `:time` default to *TIME* check this https://stackoverflow.com/questions/3928275/in-ruby-on-rails-whats-the-difference-between-datetime-timestamp-time-and-da. I want to ask how you got `ActiveSupport::TimeWithZone`? – Pavan Jun 13 '17 at 10:12
  • 1
    @pavan The question doesn't say `DateTime`, it says `date_time` which is not a real thing. It also says `date time` which is also not a thing. Most people coming to this question from Google are going to be referring to ActiveRecord models with `TimeWithZone` (this is how I discovered it), and your answer is incorrect in that case. I assume that OP meant Article was an ActiveRecord model, and that `created_at` and `updated_at` are the default `TimeWithZone`, not `DateTime` OP also says times are in Time Zone of India. `DateTime` does not contain that information. – Doug Jun 13 '17 at 20:02
  • @Doug Lets not heatup the argument here. I agree that the Question is bit unclear and also misleading. But I don't agree with `DateTime` don't have `TimeZone`. It does **has time zones**. The `+530` in my example is the `timezone`. You can check the [*docs*](https://ruby-doc.org/stdlib-2.3.1/libdoc/date/rdoc/DateTime.html). I hope OP clears some confusion so that we both can end up as good! – Pavan Jun 14 '17 at 04:51
  • 1
    Fair enough. I've updated my answer to specify that it works with `TimeWithZone` Unfortunately I am unable to edit my comment. – Doug Jun 14 '17 at 15:25
  • WRONG! do not use this method. Use @Doug method. – victorhazbun Nov 09 '17 at 03:55
  • The above calculation is wrong. the difference between two times returns seconds, dividing it by 60 you can convert it into minutes. It should be (updated - created)/60 – Naveen Thonpunoori Jul 11 '21 at 06:10
1

looking at helper time_ago_in_words, we can say:

    from_time = from_time.to_time if from_time.respond_to?(:to_time)
    to_time = to_time.to_time if to_time.respond_to?(:to_time)
    #absolute distance:
    from_time, to_time = to_time, from_time if from_time > to_time
    distance_in_minutes = ((to_time - from_time)/60.0).round
simo
  • 23,342
  • 38
  • 121
  • 218
0

The data type of ActiveRecord's columns created_at and updated_at is ActiveSupport::TimeWithZone. If you want to do the operation with DateTime, you need to convert it first

now = DateTime.now
creation_time = user.created_at.to_datetime        
diff_in_minutes = ((now - creation_time) * 24 * 60).to_i

You can test this easily in the Rails console, but for easier testing, you can convert it to seconds instead

diff_in_seconds = ((now - creation_time) * 24 * 60 * 60).to_i
hqt
  • 29,632
  • 51
  • 171
  • 250
-1

This is what i used and it simply takes care of days or Min's for you as well as giving you the difference time_ago_in_words simply pass a Datetime, Date or Time object and it will return the difference that is human readable. time_ago_in_words(@post.created_at)

ZainNazirButt
  • 377
  • 5
  • 13