irb(main):001:0> RUBY_VERSION
=> "2.0.0"
irb(main):002:0> Time.at(2**62-1).utc # within Integer range
=> 146138514283-06-19 07:44:38 UTC
irb(main):003:0> Time.at(2**128).utc # outside of Integer range
=> 10783118943836478994022445751222-08-06 08:03:51 UTC
irb(main):004:0> Time.at(-2**128).utc # outside of Integer range
=> -10783118943836478994022445747283-05-28 15:55:44 UTC
# 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
88
我发现使用DateTime, assuming you are using the ActiveSupport extensions 更容易解析和计算不同时区的一天的开始/结束 .
irb(main):034:0> DateTime.parse('2012-10-10 10:10 +0300').end_of_day
=> Wed, 10 Oct 2012 23:59:59 +0300
# it preserved the timezone +0300
现在让我们以与时间相同的方式尝试:
irb(main):035:0> Time.parse('2012-10-10 10:10 +0300').end_of_day
=> 2012-10-10 23:59:59 +0000
# the timezone got changed to the server's default UTC (+0000),
# which is not what we want to see here.
7 回答
较新版本的Ruby(2.0)在两个类之间并没有真正的显着差异 . 由于历史原因,一些图书馆将使用其中一个,但新代码不一定需要关注 . 选择一个以保持一致性可能是最好的,因此请尝试与您的库所期望的相匹配 . 例如,ActiveRecord更喜欢DateTime .
在Ruby 1.9之前的版本中以及许多系统上,Time表示为一个32位有符号值,描述自1970年1月1日UTC以来的秒数,这是一个围绕POSIX标准
time_t
值的薄包装,并且有界:较新版本的Ruby能够处理更大的值而不会产生错误 .
DateTime是一种基于日历的方法,其中单独存储年,月,日,小时,分钟和秒 . 这是一个Ruby on Rails构造,用作SQL标准DATETIME字段的包装器 . 这些包含任意日期,几乎可以表示任何时间点,因为表达范围通常非常大 .
因此,令人放心的是,DateTime可以处理来自亚里士多德的博客文章 .
选择一个时,差异在某种程度上是主观的 . 从历史上看,DateTime提供了以日历方式操作它的更好选项,但是其中许多方法也已移植到Time,至少在Rails环境中 .
[编辑2018年7月]
以下所有内容在Ruby 2.5.1中仍然适用 . 来自reference documentation:
之前在这个帖子中没有注意到的是
DateTime
的几个优点之一:它知道日历改革而Time
不是:参考文件最后建议在专门处理近期,当前或未来的日期/时间时使用
Time
并且仅在使用DateTime
时,例如莎士比亚的生日需要准确转换:(强调添加)[/编辑2018年7月]
从ruby 2.0开始,其他答案中的大部分信息都已过时 .
特别是,
Time
现在几乎没有绑定 . 它可以比Epoch更多或更少甚至63位:使用较大值的唯一结果应该是性能,这在使用
Integer
时更好(相对于Bignum
s(Integer
范围之外的值)或Rational
s(跟踪纳秒时)):换句话说,据我所知, DateTime no longer covers a wider range of potential values than Time .
此外,应该注意两个先前未提及的
DateTime
限制:首先, DateTime has no concept of leap seconds:
其次, DateTime 对时区的理解非常有限,特别是 has no concept of daylight savings . 它几乎将时区作为简单的UTC X偏移处理:
当输入DST时间然后转换为非DST时区而不跟踪
DateTime
本身之外的正确偏移时,这可能会造成麻烦(许多操作系统实际上可能已经为您处理了这个问题) .总的来说,我认为现在
Time
对大多数人来说是更好的选择应用 .另请注意添加的重要区别:当您向Time对象添加数字时,它会以秒为单位计算,但是当您向DateTime添加数字时,它会以天为单位计算 .
Outdated! See below...
性能差异不够强调......时间是C,而DateTime是Ruby:
更新(2012年2月):
正如评论中已经提到的,1.9.3已经大大提高了
DateTime
性能:我认为“有什么不同”的答案是Ruby标准库中这个问题的一个不幸的常见答案:两个类/库是由不同的人在不同时间创建的 . 与精心策划的Java开发相比,这是Ruby发展的社区性质的不幸后果之一 . 开发人员需要新的功能,但不想踩到现有的API,因此他们只是创建一个新类 - 对于最终用户来说,没有明显的理由让这两个存在 .
对于一般的软件库来说也是如此:通常,某些代码或API的结果是历史而非逻辑 .
诱惑是从DateTime开始,因为它似乎更通用 . 日期......和时间,对吧?错误 . 时间也更好地更新日期,实际上可以解析DateTime不能的时区 . 它也表现得更好 .
我到处都在使用Time .
为了安全起见,我倾向于允许将DateTime参数传递给我的Timey API,并进行转换 . 另外,如果我知道两者都有我感兴趣的方法,我也接受,就像我写的用于将时间转换为XML(用于XMLTV文件)的方法
我发现使用DateTime, assuming you are using the ActiveSupport extensions 更容易解析和计算不同时区的一天的开始/结束 .
在我的情况下,我需要根据用户的本地时间以字符串形式计算用户时区(任意)的一天结束时间,例如: “2012-10-10 10:10 0300”
使用DateTime就像它一样简单
现在让我们以与时间相同的方式尝试:
实际上,Time需要在解析之前知道时区(还要注意它是
Time.zone.parse
,而不是Time.parse
):所以,在这种情况下,使用DateTime肯定更容易 .
考虑他们如何使用自定义实例化以不同方式处理时区:
在创建时间范围等时这可能很棘手 .
在某些情况下,行为似乎非常不同: