Ruby中的DateTime和Time之间的区别
Ruby中的DateTime
和Time
类有什么区别,以及哪些因素会导致我选择其中一个?
较新版本的Ruby(2.0+)在两个类之间并没有真正的显着差异。 由于历史原因,一些图书馆会使用其中一种,但新代码不一定需要担心。 为了一致性选择一个可能是最好的,所以尝试和你的图书馆期望的网格。 例如,ActiveRecord倾向于使用DateTime。
在Ruby 1.9之前的版本和许多系统上,Time被表示为一个32位有符号值,描述自UTC 1970年1月1日以来的秒数,UTC是一个围绕POSIX标准time_t
值的薄包装,并且有界:
Time.at(0x7FFFFFFF)
# => Mon Jan 18 22:14:07 -0500 2038
Time.at(-0x7FFFFFFF)
# => Fri Dec 13 15:45:53 -0500 1901
较新版本的Ruby能够处理较大的值而不会产生错误。
DateTime是一种基于日历的方法,其中年,月,日,小时,分钟和秒分别存储。 这是一个Ruby on Rails构造,用作SQL标准DATETIME字段的包装。 这些包含任意日期,并且由于表达范围通常非常大,因此可以表示几乎任何时间点。
DateTime.new
# => Mon, 01 Jan -4712 00:00:00 +0000
所以DateTime可以处理来自亚里士多德的博客帖子令人放心。
当选择一个时,差异现在有点主观。 从历史上看,DateTime提供了更好的日历方式来操作它,但其中许多方法也已移植到Time,至少在Rails环境中。
截至ruby 2.0,大部分上述信息已过时。
特别是, Time
现在几乎不受限制。 它可以比Epoch更多甚至更少63位:
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
使用较大值的唯一结果应该是性能,当使用Integer
时(与Bignum
s( Integer
范围之外的值)或Rational
s(当跟踪纳秒时))会更好:
从Ruby 1.9.2开始,Time实现使用带符号的63位整数Bignum或Rational。 整数是从Epoch开始的纳秒数,它可以表示1823-11-12到2116-02-20。 当使用Bignum或Rational(1823年之前,2116之后,纳秒)时,Time与使用整数时相比运行速度更慢。 (http://www.ruby-doc.org/core-2.1.0/Time.html)
换句话说,就我所知, DateTime
不再覆盖比Time
更广泛的潜在值 。
另外,可能会注意到以前未提及的DateTime
限制:
DateTime不考虑任何超时,不跟踪任何夏令时规则。 (http://www.ruby-doc.org/stdlib-2.1.0/libdoc/date/rdoc/Date.html#class-Date-label-DateTime)
首先, DateTime
没有闰秒的概念:
irb(main):001:0> RUBY_VERSION
=> "2.0.0"
irb(main):002:0> require "date"
=> true
irb(main):003:0> t = Time.new(2012,6,30,23,59,60,0)
=> 2012-06-30 23:59:60 +0000
irb(main):004:0> dt = t.to_datetime; dt.to_s
=> "2012-06-30T23:59:59+00:00"
irb(main):005:0> t == dt.to_time
=> false
irb(main):006:0> t.to_i
=> 1341100824
irb(main):007:0> dt.to_i
=> 1341100823
其次, DateTime
对时区的理解非常有限,特别是没有夏令时的概念 。 它几乎处理时区为简单的UTC + X偏移量:
irb(main):001:0> RUBY_VERSION
=> "2.0.0"
irb(main):002:0> require "date"
=> true
irb(main):003:0> t = Time.local(2012,7,1)
=> 2012-07-01 00:00:00 +0200
irb(main):004:0> t.zone
=> "CEST"
irb(main):005:0> t.dst?
=> true
irb(main):006:0> dt = t.to_datetime; dt.to_s
=> "2012-07-01T00:00:00+02:00"
irb(main):007:0> dt.zone
=> "+02:00"
irb(main):008:0> dt.dst?
NoMethodError: undefined method `dst?' for #<DateTime:0x007f34ea6c3cb8>
当输入时间作为DST时,这可能会造成麻烦,然后转换为非DST时区而未跟踪DateTime
本身之外的正确偏移量(许多操作系统实际上可能已经为您处理此问题)。
总的来说,我想说Time
对于大多数应用来说是更好的选择。
另外还要注意一个重要的不同之处:当您向Time对象添加数字时,它会以秒为单位进行计数,但当您将数字添加到DateTime时,则会以天计算。
过时! 见下文...
性能差异不能被足够强调...时间是C,DateTime是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)
更新(2/2012):
正如评论中已经提到的那样,1.9.3大大提高了DateTime
性能:
user system total real
DateTime: 0.330000 0.000000 0.330000 ( 0.333869)
Time: 0.300000 0.000000 0.300000 ( 0.306444)
链接地址: http://www.djcxy.com/p/95407.html
上一篇: Difference between DateTime and Time in Ruby
下一篇: How to generate a human readable time range using ruby on rails