views:

1483

answers:

3

And what factors would cause me to choose one or the other?

+12  A: 

Time is a wrapper around POSIX-standard time_t, or seconds since January 1, 1970. This can be expressed as a positive or negative number, 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

Values outside those bounds produce an error.

In contrast, DateTime is much more open-ended. The more robust version 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.

tadman
So should I always use DateTime?
Horace Loeb
If you're working with dates, I'd say use DateTime. Time is convenient for representing things such as current time of day, or points in the near future such as 10.minutes.from_now. The two have a lot in common, though as noted DateTime can represent a much wider range of values.
tadman
> Time is convenient for representing things such as current time of day, or points in the near future such as 10.minutes.from_now.Why is Time more convenient than DateTime for this purpose?
Horace Loeb
Time.now is just more concise than DateTime.now, but they are functionally similar. It is mostly a matter of preference so long as the date values are supported by both.
tadman
+5  A: 

I think the answer to "what's the difference" is one of the unfortunate common answers to this question in the Ruby standard libraries: the two classes/libs were created differently by different people at different times. It's one of the unfortunate consequences of the community nature of Ruby's evolution compared to carefully planned development of something like Java. Developers want new functionality but don't want to step on existing APIs so they just create a new class - to the end user there's no obvious reason for the two to exist.

This is true for software libraries in general: often the reason some code or API is the way it is turns out to be historical rather than logical.

The temptation is to start with DateTime because it seems more generic. Date... and Time, right? Wrong. Time also does dates better, and in fact can parse timezones where DateTime can't. Also it performs better.

I've ended up using Time everywhere.

To be safe though, I tend to allow for DateTime arguments to be passed into my Timey APIs, and either convert. Also if I know that both have the method I'm interested in I accept either, like this method I wrote for converting times to XML (for XMLTV files)

# Will take a date time as a string or as a Time or DateTime object and
# format it appropriately for xmtlv. 
# For example, the 22nd of August, 2006 at 20 past midnight in the British Summertime
# timezone (i.e. GMT plus one hour for DST) gives: "20060822002000 +0100"
def self.format_date_time(date_time)
  if (date_time.respond_to?(:rfc822)) then
    return format_time(date_time)
  else 
    time = Time.parse(date_time.to_s)
    return format_time(time)
  end    
end

# Note must use a Time, not a String, nor a DateTime, nor Date.
# see format_date_time for the more general version
def self.format_time(time)
  # The timezone feature of DateTime doesn't work with parsed times for some reason
  # and the timezone of Time is verbose like "GMT Daylight Saving Time", so the only
  # way I've discovered of getting the timezone in the form "+0100" is to use 
  # Time.rfc822 and look at the last five chars
  return "#{time.strftime( '%Y%m%d%H%M%S' )} #{time.rfc822[-5..-1]}"
end
Rhubarb
+9  A: 

The performance difference can't be emphasized enough... Time is C, and DateTime is Ruby:

>> Benchmark.bm do |bm|
?>   bm.report('DateTime:') do
?>     n1 = DateTime.now
>>     n2 = DateTime.now
>>     1_000_000.times{ n1 < n2 }
>>   end
>>   bm.report('Time:    ') do
?>     n1 = Time.now
>>     n2 = Time.now
>>     1_000_000.times{ n1 < n2 }
>>   end
>> end
      user     system      total        real
DateTime:  4.980000   0.020000   5.000000 (  5.063963)
Time:      0.330000   0.000000   0.330000 (  0.335913)
Mladen Jablanović