0

I m very new to Ruby, want to understand the best practise in time comparison

I have expireAt timestamp from an object where I need to apply some logic and compare with current time. Having that background in mind.

Which is better approach,

if Time.now.to_i < obj.expireAt
  // some logic
end

or

if Time.now < Time.at(obj.expireAt)
  // some logic
end

Thanks in advance!

Arun G
  • 1,678
  • 15
  • 17
  • 1
    What is the class of `obj.expireAt`? Based on your code, it appears to be a simple integer. Best practice in Ruby would be to make that attribute of the object an instance of `Time` or `DateTime` in the first place, and do the conversion only once wherever that value is set. Then at the point of your code you would just do `Time.now < obj.expireAt` without calling either `to_i` or `Time.at`. – Mark Reed Feb 03 '17 at 05:41
  • `obj.expireAt` is simple integer (timestamp). Can you explain me why its best to compare with Time or DateTime. Just curious to know. – Arun G Feb 03 '17 at 06:30
  • 1
    Because it's self-documenting and self-contained that way. You can inspect an object and determine what its class is; if its `Fixnum`, that doesn't tell you anything useful about it. You have to somehow know that it is a timestamp and how to convert it to an actual time value. If it's a `Time`, not only do you then know what it is, but you have all the methods of that class available to manipulate it. Everything in Ruby is an instance of some class; you might as well use the one that matches what your value is for. – Mark Reed Feb 03 '17 at 07:13
  • @MarkReed You are rite about it. Will accept answer if you could add one :+1 – Arun G Feb 06 '17 at 05:12

2 Answers2

1

Based on your code, obj.expireAt appears to be a simple integer. Normal best practice in Ruby would be to make that attribute of the object an instance of Time or DateTime instead. (See this question for discussion of the differences between those two options.) If your data comes in as integers, do the conversion once when storing the value in the instance variable, rather than repeatedly when accessing it for other purposes. You can always cache the integer and make it available as well via another method if you need to get it back out without running the conversion backwards.

This is considered best practice because it makes the attribute self-documenting and self-contained. You can inspect an object and determine what its class is (although doing so programmatically is considered bad form in Ruby, where we generally prefer Duck Typing). If I look at the value I get back from expireAt and see that it's a Fixnum, that doesn't tell me anything useful about it. I have to infer that it is a timestamp, and do extra work to convert it to a value with useful time-related semantics. Whereas if it's a Time, not only do I know what it is, but I have all the methods of that class available to manipulate it.

Since everything in Ruby is an object (and therefore an instance of some class), you might as well use a class designed to be used the way your value is used.

Community
  • 1
  • 1
Mark Reed
  • 91,912
  • 16
  • 138
  • 175
0

If you've got a value in the database that's interpreted as a DateTime value by Rails then do this:

if Time.now < obj.expire_at
  # ...
end

There's no need to convert with at or to_i. In many cases that's pointless and wasteful.

Using a literal TIMESTAMP column is often sub-optimal, that's a weak datatype in MySQL that's convenient in that it's auto-populated, but it's also bounded, values can't be beyond the year 2038, setting yourself up for an inevitable Y2K type problem.

Also note that Ruby on Rails strongly encourages all-lowercase variable and column names. expireAt is highly irregular.

tadman
  • 208,517
  • 23
  • 234
  • 262
  • Please read my question. I m seeking answer in pure ruby. No Rails framework. – Arun G Feb 03 '17 at 05:35
  • 1
    Do note you tagged your question Rails which is usually a strong indicator of your answer preference. The same advice applies. – tadman Feb 03 '17 at 05:37
  • Thanks for that info. Removed my tag. We can't really compare timestamp with Time object. – Arun G Feb 03 '17 at 05:40
  • What database adapter layer are you using? [Sequel](https://github.com/jeremyevans/sequel) is a very no-nonsense, lightweight layer that's worked very well for me and it does a lot of this conversion for you. Are you using a literal UNIX `time_t` timestamp value or a `TIMESTAMP` column? You need to be specific about these things and give examples. – tadman Feb 03 '17 at 05:41