Difference between DateTime and Time in Ruby
Newer versions of Ruby (2.0+) do not really have significant differences between the two classes. Some libraries will use one or the other for historical reasons, but new code does not necessarily need to be concerned. Picking one for consistency is probably best, so try and mesh with what your libraries expect. For example, ActiveRecord prefers DateTime.
In versions prior to Ruby 1.9 and on many systems Time is represented as a 32-bit signed value describing the number of seconds since January 1, 1970 UTC, a thin wrapper around a POSIX-standard time_t
value, and is bounded:
Time.at(0x7FFFFFFF)
# => Mon Jan 18 22:14:07 -0500 2038
Time.at(-0x7FFFFFFF)
# => Fri Dec 13 15:45:53 -0500 1901
Newer versions of Ruby are able to handle larger values without producing errors.
DateTime is a calendar-based approach where the year, month, day, hour, minute and second are stored individually. This is a Ruby on Rails construct that serves as a wrapper around SQL-standard DATETIME fields. These contain arbitrary dates and can represent nearly any point in time as the range of expression is typically very large.
DateTime.new
# => Mon, 01 Jan -4712 00:00:00 +0000
So it's reassuring that DateTime can handle blog posts from Aristotle.
When choosing one, the differences are somewhat subjective now. Historically DateTime has provided better options for manipulating it in a calendar fashion, but many of these methods have been ported over to Time as well, at least within the Rails environment.
Difference in hours between 2 DateTime
First of all, from the docs:
So when should you use
DateTime
in Ruby and when should you useTime
? Almost certainly you’ll want to useTime
since your app is probably dealing with current dates and times. However, if you need to deal with dates and times in a historical context you’ll want to useDateTime
...
If you want to continue using DateTime
, its subtraction method gives you the difference in fractions of a day
DateTime.new(2000, 1, 3) - DateTime.new(2000, 1, 1)
# (2/1)
Getting that into hours is actually kind of impossible because there aren't always 24 hours per day. You need to convert to Time
objects to get the difference in seconds, then convert from seconds to hours
diff_in_hours = (dt1.to_time - dt2.to_time) / 3_600
In Ruby on Rails, what's the difference between DateTime, Timestamp, Time and Date?
The difference between different date/time formats in ActiveRecord has little to do with Rails and everything to do with whatever database you're using.
Using MySQL as an example (if for no other reason because it's most popular), you have DATE
, DATETIME
, TIME
and TIMESTAMP
column data types; just as you have CHAR
, VARCHAR
, FLOAT
and INTEGER
.
So, you ask, what's the difference? Well, some of them are self-explanatory. DATE
only stores a date, TIME
only stores a time of day, while DATETIME
stores both.
The difference between DATETIME
and TIMESTAMP
is a bit more subtle: DATETIME
is formatted as YYYY-MM-DD HH:MM:SS
. Valid ranges go from the year 1000 to the year 9999 (and everything in between. While TIMESTAMP
looks similar when you fetch it from the database, it's really a just a front for a unix timestamp. Its valid range goes from 1970 to 2038. The difference here, aside from the various built-in functions within the database engine, is storage space. Because DATETIME
stores every digit in the year, month day, hour, minute and second, it uses up a total of 8 bytes. As TIMESTAMP
only stores the number of seconds since 1970-01-01, it uses 4 bytes.
You can read more about the differences between time formats in MySQL here.
In the end, it comes down to what you need your date/time column to do:
- Do you need to store dates and times before 1970 or after 2038? => Use
DATETIME
. - Do you need to worry about database size and you're within that timerange? => Use
TIMESTAMP
. - Do you only need to store a date? => Use
DATE
. - Do you only need to store a time? => Use
TIME
.
Having said all of this, Rails actually makes some of these decisions for you. Both :timestamp
and :datetime
will default to DATETIME
, while :date
and :time
corresponds to DATE
and TIME
, respectively.
This means that within Rails, you only have to decide whether you need to store date, time or both.
When should i use DateTime vs date, time fields in ruby/rails?
The general idea is to use a DateTime as a general purpose representation of time. Where you might be confused is that Time also includes a date component as it is an encapsulation of the UNIX time_t
concept of seconds since epoch, or UNIX_TIME()
in MySQL terms.
As I explain in another answer, Time is a more limited representation than DateTime and can only represent dates and times up to Jan 18, 2038. A DateTime can represent 4,712 BCE as well as 21,000 years in the future.
If you want a separate field that represents time of day, which it seems like you might want here, you should create a single numerical field that represents either seconds past midnight if that kind of precision is required, or a more convenient "HHMM" representation that doesn't concern itself with the differences between base-60 and base-10.
Another alternative is to have two fields, one being a DateTime and one being a Date. If you're creating a calendar entry with no particular time, populate only the Date field. If it has a time, populate both.
Remember that a date field is populated with a literal date and does not concern itself with time zones, so this can cause trouble if it is not expressed in the user's local time. A DateTime can always be converted to a user's local time if required.
Are the Date, Time, and DateTime classes necessary?
DateTime
is a subclass of Date
, so whatever you can do with Date
can be done with DateTime
. But as tadman and steenslag point out, DateTime
is slower. See steenslag's answer for how much slower it is.
With respect to DateTime
vs, Time
, I found something here:
Time is a wrapper around Unix-Epoch.
Date (and DateTime) use rational and a "day zero" for storage. So Time is faster but the upper and lower bounds are tied to epoch time (which for 32bit epoch times is something around 1970-2040...while Date (and DateTime) have an almost infinite range but are terribly slow.
In short, DateTime
is an all around superstar, and should be preferred in general, but if you want to optimize to the last bit, using Time
can improve performance.
Why does between? work differently for Date and DateTime in ruby?
Lets launch irb and run those code:
"#{DateTime.now.inspect} \n #{DateTime.now.inspect}"
Result'll be something like this:
#<DateTime: 2017-03-22T11:42:28+03:00 ((2457835j,31348s,373353553n),+10800s,2299161j)>
#<DateTime: 2017-03-22T11:42:28+03:00 ((2457835j,31348s,373449152n),+10800s,2299161j)>
As you can see, there is difference in nanoseconds (373353553n < 373449152n)
Lets imagine that difference is equal to 'x', and DateTime.now is equal to 'Now', then:
1) DateTime.now.between?(DateTime.now, DateTime.now+1.second)
Now.between?(Now+x, Now+x+x+1.second) => false
2) DateTime.now.between?(DateTime.now-1, DateTime.now)
Now.between?(Now+x-1.second, Now+x+x) => true
Ruby difference between two dates
Date
does not include Time
. Use DateTime
instead.
require 'date'
dt = DateTime.rfc3339('2017-08-16T17:55:49.000-03:00')
puts (Time.now - dt.to_time)/(60*60) > 24
Time difference in hours
((date_2 - date_1) / 3600).round
or
((date_2 - date_1) / 1.hour).round
How to find the difference between two time in ruby?
If you want it in seconds, you can just convert both to time stamps, and then subtract
time_difference_in_sec = (DateTime.now.to_time.to_i - @given_time.to_time.to_i).abs
Else you wind up dealing with rational numbers, and the like as seen in the other answers..
Related Topics
Installed Ruby 1.9.3 With Rvm But Command Line Doesn't Show Ruby -V
What Is Ruby'S Double-Colon '::'
Why Is Division in Ruby Returning an Integer Instead of Decimal Value
Ruby Class Instance Variable Vs. Class Variable
How to Write a Switch Statement in Ruby
How to Get a Random Number in Ruby
Where and How Is the _ (Underscore) Variable Specified
Rails 4: List of Available Datatypes
Ruby 1.9: Invalid Byte Sequence in Utf-8
How to Generate a Random String in Ruby
How to Test If a String Is Basically an Integer in Quotes Using Ruby
Combining Implicit Wait and Explicit Wait Together Results in Unexpected Wait Times
How to Parse Json With Ruby on Rails