Date,Time和DateTime类是必需的吗?

如果有一个DateTime类可以处理这两个类,那么具有DateTime类的目的是什么?

DateTimeDate一个子类,所以你可以用Date来做什么。 但是正如tadman和steenslag指出的那样, DateTime比较慢。 看到steenslag的答案是多慢。

关于DateTimeTime ,我在这里find了一些东西。

引文


 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. 

总之, DateTime是一个全能的超级明星,应该是一般的首选,但如果你想优化到最后一点,使用Time可以提高性能。

总结一下常见的ruby时间类是什么:

Time

这是基本的主力核心ruby时间类。

  • 具有date和时间属性(年,月,日,小时,分,秒,小秒)
  • 基于unix时代的浮点二次间隔(1970-01-01)
  • unix时代可以处理负面的时代
  • 可以以秒为单位处理时间算术
  • 本地工作在UTC或“本地”(系统时区)

说到处理时区,真的有3种时间对象,让我们看看夏天的时间来显示DST:

 utc = Time.utc(2012,6,1) # => 2012-12-21 00:00:00 UTC utc.zone # => "UTC" utc.dst? # => false utc.utc? # => true utc.utc_offset # => 0 local = Time.local(2012,6,1) # => 2012-06-01 00:00:00 -0700 local.zone # => "PDT" local.dst? # => true local.utc? # => false local.utc_offset # => -25200 nonlocal = Time.new(2012,6,1,0,0,0, "-07:00") # => 2012-06-01 00:00:00 -0700 nonlocal.zone # => nil nonlocal.dst? # => false nonlocal.utc? # => false nonlocal.utc_offset # => -25200 

最后2看起来相似,但要小心: 你不应该用非本地时间做算术 。 这只是一个UTC偏移和没有区域的时间,所以它不知道DST的规则。 在DST边界上添加时间不会改变偏移量,所产生的时间将是错误的。

ActiveSupport::TimeWithZone

这里值得一提,因为这是你在Rails中使用的。 和时间一样,再加上:

  • 可以处理任何时区
  • 尊重DST
  • 可以转换区域之间的时间

当ActiveSupport可用时,我通常总是这样做,因为它负责处理所有的时区陷阱。

Date

  • 只有date属性(年,月,日)
  • 基于从任意“date零”(-4712-01-01)开始的整数整日间隔,
  • 可以以整天为单位处理date算术
  • 可以在古代儒略历中的date之间转换为现代格里高利

date比时间更有用,每当你整天处理:没有时区担心! (我很惊讶,这不涉及现代波斯历,因为它知道几个世纪以前的朱利安历法。)

DateTime

  • 具有date和时间属性(年,月,日,时,分,秒)
  • 根据任意“零日”(-4712-01-01)的全天间隔的小数部分,
  • 可以以整天或分数为单位处理date算术

就我个人而言,我从来没有理由使用它:它很慢,它处理时间,而不考虑时区,它有一个不一致的接口。 我发现每当你假设你有一个Time-like对象时,它就会导致混淆,但实际上它的行为就像是一个Date

 Time.new(2012, 12, 31, 0, 0, 0) + 1 == Time.new(2012, 12, 31, 0, 0, 1) DateTime.new(2012, 12, 31, 0, 0, 0) + 1 == DateTime.new(2013, 1, 1, 0, 0, 0) 

此外,它具有无意义的“区域”属性(请注意非本地时间对象如何警告您该zone == nil ),并且在将其先变为时间之前,您无法了解其他任何信息:

 dt = DateTime.new(2012,12,6, 1, 0, 0, "-07:00") dt.zone # => "-07:00" dt.utc? # => NoMethodError: undefined method `utc?' dt.dst? # => NoMethodError: undefined method `dst?' dt.utc_offset # => NoMethodError: undefined method `utc_offset' 

处理微秒检查舍入也有点奇怪。 你会认为,因为它没有一个usec属性,它只处理整个数字,但你会错的:

 DateTime.now.usec # => NoMethodError: undefined method `usec' DateTime.now.to_time.usec => 629399 

简而言之,除非您在古代处理天文事件,并且需要将Juliandate(一天中的时间)转换为现代日历,否则请勿使用DateTime。 如果有人有这个类的实际用例,我很乐意阅读你的意见。

我知道有一个被接受的答案,但我有一些补充。 Date类是一个重量级的学术力量课。 它可以处理各种RFC,parsing最奇怪的事情,并把朱连的date从千年前改为公历。 Time类是轻量级的,它不知道这些东西。 它更便宜,并以基准显示:

 require 'benchmark' require 'date' Benchmark.bm(10) do |x| x.report('date'){100000.times{Date.today} } x.report('datetime'){100000.times{DateTime.now} } x.report('time'){100000.times{Time.now} } end 

结果:

  user system total real date 1.250000 0.270000 1.520000 ( 1.799531) datetime 6.660000 0.360000 7.020000 ( 7.690016) time 0.140000 0.030000 0.170000 ( 0.200738) 

(Ruby 1.9.2)

另一种思考的方法是DateDateTime模型时钟和日历,这对于向用户描述时间和安排事件是很有用的。 有一个没有时间的Date是很好的,当你不关心的时间,你不想考虑时区。

Time模型是一个连续统一体,是Unix时间戳的一个包装,它只是一个整数。 这对于所有内部应用程序都很有用,在这种应用程序中,计算机不关心日历边界是否已经越过,而是多less秒(或毫秒)已经过去。

是。 date只处理1989年3月31日IE的date。但它不处理时间,例如12:30 PM。 date时间,可以处理,1989年3月31日下午12:30东部时间。

有时你不需要DateTime的所有部分。 例如,你想知道什么时候使用注册你的网站,date在这里是有用的,因为时间最终是不相关的。

在某些情况下,您可能只需要时间。 例如,如果是午餐时间,您可能要告诉用户您的办公室已closures。 在这一点上,数据是无关紧要的。

但是,在大多数情况下使用DateTime,因为它可以用作date,时间或两者。