Ruby中的DateTime和Time之间的差异

时间:2021-06-09 21:34:00

What's the difference between DateTime and Time classes in Ruby and what factors would cause me to choose one or the other?

Ruby中的DateTime和Time类之间的区别是什么?是什么因素导致我选择其中一个?

7 个解决方案

#1


164  

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.

Ruby(2.0+)的更新版本在这两个类之间并没有明显的区别。由于历史原因,一些库将使用其中一个或另一个,但并不一定需要关注新的代码。为一致性选择一个可能是最好的,所以尝试与您的库期望的一致。例如,ActiveRecord更喜欢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:

在Ruby 1.9和许多系统时间之前的版本中,有一个32位的签名值,描述自1970年1月1日以来的秒数,它是一个围绕POSIX-standard time_t值的薄包装,并且是有界的:

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.

新版本的Ruby能够处理较大的值而不会产生错误。

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是一种基于日历的方法,它将年、月、日、小时、分钟和秒分别存储。这是一个Ruby on Rails构造,它作为sql标准DATETIME字段的包装器。它们包含任意的日期,可以表示几乎任何时间点,因为表达式的范围通常非常大。

DateTime.new
# => Mon, 01 Jan -4712 00:00:00 +0000

So it's reassuring that DateTime can handle blog posts from Aristotle.

因此,DateTime可以处理来自亚里士多德的博客文章。

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.

在选择时,现在的差异有些主观。在历史上,DateTime提供了一种更好的日历方式来操作它的选项,但是这些方法中的许多也随着时间的推移被移植,至少在Rails环境中是这样。

#2


79  

As of ruby 2.0, most of the aforementioned information is out of date.

到ruby 2.0的时候,上面提到的大多数信息都已经过时了。

In particular, Time is now practically unbound. It can be more or less than even 63 bits away from 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

The only consequence of using larger values should be performance, which is better when Integers are used (vs. Bignums (values outside of Integer range) or Rationals (when nanoseconds are tracked)):

使用较大值的唯一结果应该是性能,当使用整数时性能更好(与Bignums(整数范围之外的值)或合理化(跟踪纳秒时):

Since Ruby 1.9.2, Time implementation uses a signed 63 bit integer, Bignum or Rational. The integer is a number of nanoseconds since the Epoch which can represent 1823-11-12 to 2116-02-20. When Bignum or Rational is used (before 1823, after 2116, under nanosecond), Time works slower as when integer is used. (http://www.ruby-doc.org/core-2.1.0/Time.html)

由于Ruby 1.9.2,时间实现使用一个带符号的63位整数、Bignum或Rational。该整数是自纪元以来的纳秒数,可以表示1823-11-12到2116-02-20。当使用Bignum或Rational时(在1823年之前,在2116年之后,在纳秒之下),使用integer时时间工作得更慢。(http://www.ruby-doc.org/core-2.1.0/Time.html)

In other words, as far as I understand, DateTime no longer covers a wider range of potential values than Time.

换句话说,就我所知,DateTime不再包含比Time更广泛的潜在值范围。

In addition, two previously unmentioned restrictions of DateTime should probably be noted:

此外,前面提到的两个DateTime限制可能应该注意:

DateTime does not consider any leapseconds, does not track any summer time rules. (http://www.ruby-doc.org/stdlib-2.1.0/libdoc/date/rdoc/Date.html#class-Date-label-DateTime)

DateTime不考虑任何闰秒,也不跟踪任何夏季时间规则。(http://www.ruby-doc.org/stdlib-2.1.0/libdoc/date/rdoc/Date.html # class-Date-label-DateTime)

First, DateTime has no concept of leap seconds:

首先,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

Second, DateTime has very limited understanding of time zones and in particular has no concept of daylight savings. It pretty much handles time zones as simple UTC + X offsets:

其次,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>

This may cause trouble when times are entered as DST and then converted into a non-DST time zone without keeping track of the correct offsets outside of DateTime itself (many operating systems may actually already take care of this for you).

当时间被输入为DST,然后转换为非DST时区,而不跟踪DateTime本身之外的正确偏移量时,这可能会带来麻烦(许多操作系统实际上可能已经为您处理了这一点)。

Overall, I'd say that nowadays Time is the better choice for most applications.

总的来说,我认为现在对大多数应用来说时间是更好的选择。

Also note an important difference on addition: when you add a number to a Time object, it is counted in seconds, but when you add a number to a DateTime, it is counted in days.

还要注意加法的一个重要区别:当你向时间对象添加一个数字时,它是以秒为单位的,但是当你向时间对象添加一个数字时,它是以天为单位的。

#3


66  

Outdated! See below...

过时的!见下文……

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

性能差异再怎么强调都不为过……时间是C,时间是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)

Update (2/2012):

更新(2/2012):

As already mentioned in the comment, 1.9.3 has vastly improved DateTime performance:

正如评论中已经提到的,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)

#4


42  

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.

我认为“有什么不同”的答案是Ruby标准库中这个问题的一个不幸的常见答案:两个类/libs是由不同的人在不同的时间创建的。与精心计划的Java开发相比,这是Ruby进化的社区性质的不幸后果之一。开发人员想要新的功能,但又不想涉足现有的api,因此他们只创建了一个新类——对于最终用户来说,这两个类的存在没有明显的理由。

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.

一般来说,这对软件库是正确的:一些代码或API的原因往往是历史的,而不是逻辑的。

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.

诱惑在于从DateTime开始,因为它看起来更通用。日期……和时间,对吧?错了。时间也可以更好地处理日期,实际上可以解析DateTime不能解析的时区。也表现得更好。

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)

为了安全起见,我倾向于允许将DateTime参数传递到我的Timey api中,或者转换。如果我知道两者都有我感兴趣的方法,我接受其中任何一种,就像我编写的将时间转换为XML(用于XMLTV文件)的方法一样

# 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

#5


9  

I found such things like parsing and calculating the beginning/end of a day in different timezones are easier to do with DateTime, assuming you are using the ActiveSupport extensions.

我发现,如果您使用的是ActiveSupport扩展,那么在不同时区解析和计算一天的开始/结束之类的事情更容易处理DateTime。

In my case I needed to calculate the end of the day in a user's timezone (arbitrary) based on the user's local time which I received as a string, e.g. "2012-10-10 10:10 +0300"

在我的例子中,我需要根据用户的本地时间计算用户的时区(任意)一天的结束时间,我将用户的本地时间作为字符串接收,例如。“2012-10-10 10:10 + 0300”

With DateTime it's as simple as

有了DateTime,它就变得很简单了

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

Now let's try it the same way with Time:

现在让我们用同样的方法来研究时间:

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.

Actually, Time needs to know the timezone before parsing (also note it's Time.zone.parse, not Time.parse):

实际上,时间需要在解析之前知道时区(还要注意它是Time.zone)。解析,不是Time.parse):

irb(main):044:0> Time.zone = 'EET'
=> "EET"
irb(main):045:0> Time.zone.parse('2012-10-10 10:10 +0300').end_of_day
=> Wed, 10 Oct 2012 23:59:59 EEST +03:00

So, in this case it's definitely easier to go with DateTime.

因此,在这种情况下,使用DateTime无疑更容易。

#6


4  

Consider how they handle timezones differently with custom instantiations:

考虑一下它们如何以不同的自定义实例来处理时区:

irb(main):001:0> Time.new(2016,9,1)
=> 2016-09-01 00:00:00 -0400
irb(main):002:0> DateTime.new(2016,9,1)
=> Thu, 01 Sep 2016 00:00:00 +0000
irb(main):003:0> Time.new(2016,9,1).to_i
=> 1472702400
irb(main):004:0> DateTime.new(2016,9,1).to_i
=> 1472688000

This can be tricky when creating time ranges, etc.

这在创建时间范围时可能会很棘手。

#7


0  

It seems that in some cases the behavior is very different:

似乎在某些情况下,人们的行为非常不同:

Time.parse("Ends from 28 Jun 2018 12:00 BST").utc.to_s

"2018-06-28 09:00:00 UTC"

“2018-06-28 09:00:00 UTC”

Date.parse("Ends from 28 Jun 2018 12:00 BST").to_time.utc.to_s

"2018-06-27 21:00:00 UTC"

“2018-06-27 21:00:00 UTC”

DateTime.parse("Ends from 28 Jun 2018 12:00 BST").to_time.utc.to_s

"2018-06-28 11:00:00 UTC"

“2018-06-28 11:00:00 UTC”

#1


164  

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.

Ruby(2.0+)的更新版本在这两个类之间并没有明显的区别。由于历史原因,一些库将使用其中一个或另一个,但并不一定需要关注新的代码。为一致性选择一个可能是最好的,所以尝试与您的库期望的一致。例如,ActiveRecord更喜欢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:

在Ruby 1.9和许多系统时间之前的版本中,有一个32位的签名值,描述自1970年1月1日以来的秒数,它是一个围绕POSIX-standard time_t值的薄包装,并且是有界的:

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.

新版本的Ruby能够处理较大的值而不会产生错误。

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是一种基于日历的方法,它将年、月、日、小时、分钟和秒分别存储。这是一个Ruby on Rails构造,它作为sql标准DATETIME字段的包装器。它们包含任意的日期,可以表示几乎任何时间点,因为表达式的范围通常非常大。

DateTime.new
# => Mon, 01 Jan -4712 00:00:00 +0000

So it's reassuring that DateTime can handle blog posts from Aristotle.

因此,DateTime可以处理来自亚里士多德的博客文章。

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.

在选择时,现在的差异有些主观。在历史上,DateTime提供了一种更好的日历方式来操作它的选项,但是这些方法中的许多也随着时间的推移被移植,至少在Rails环境中是这样。

#2


79  

As of ruby 2.0, most of the aforementioned information is out of date.

到ruby 2.0的时候,上面提到的大多数信息都已经过时了。

In particular, Time is now practically unbound. It can be more or less than even 63 bits away from 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

The only consequence of using larger values should be performance, which is better when Integers are used (vs. Bignums (values outside of Integer range) or Rationals (when nanoseconds are tracked)):

使用较大值的唯一结果应该是性能,当使用整数时性能更好(与Bignums(整数范围之外的值)或合理化(跟踪纳秒时):

Since Ruby 1.9.2, Time implementation uses a signed 63 bit integer, Bignum or Rational. The integer is a number of nanoseconds since the Epoch which can represent 1823-11-12 to 2116-02-20. When Bignum or Rational is used (before 1823, after 2116, under nanosecond), Time works slower as when integer is used. (http://www.ruby-doc.org/core-2.1.0/Time.html)

由于Ruby 1.9.2,时间实现使用一个带符号的63位整数、Bignum或Rational。该整数是自纪元以来的纳秒数,可以表示1823-11-12到2116-02-20。当使用Bignum或Rational时(在1823年之前,在2116年之后,在纳秒之下),使用integer时时间工作得更慢。(http://www.ruby-doc.org/core-2.1.0/Time.html)

In other words, as far as I understand, DateTime no longer covers a wider range of potential values than Time.

换句话说,就我所知,DateTime不再包含比Time更广泛的潜在值范围。

In addition, two previously unmentioned restrictions of DateTime should probably be noted:

此外,前面提到的两个DateTime限制可能应该注意:

DateTime does not consider any leapseconds, does not track any summer time rules. (http://www.ruby-doc.org/stdlib-2.1.0/libdoc/date/rdoc/Date.html#class-Date-label-DateTime)

DateTime不考虑任何闰秒,也不跟踪任何夏季时间规则。(http://www.ruby-doc.org/stdlib-2.1.0/libdoc/date/rdoc/Date.html # class-Date-label-DateTime)

First, DateTime has no concept of leap seconds:

首先,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

Second, DateTime has very limited understanding of time zones and in particular has no concept of daylight savings. It pretty much handles time zones as simple UTC + X offsets:

其次,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>

This may cause trouble when times are entered as DST and then converted into a non-DST time zone without keeping track of the correct offsets outside of DateTime itself (many operating systems may actually already take care of this for you).

当时间被输入为DST,然后转换为非DST时区,而不跟踪DateTime本身之外的正确偏移量时,这可能会带来麻烦(许多操作系统实际上可能已经为您处理了这一点)。

Overall, I'd say that nowadays Time is the better choice for most applications.

总的来说,我认为现在对大多数应用来说时间是更好的选择。

Also note an important difference on addition: when you add a number to a Time object, it is counted in seconds, but when you add a number to a DateTime, it is counted in days.

还要注意加法的一个重要区别:当你向时间对象添加一个数字时,它是以秒为单位的,但是当你向时间对象添加一个数字时,它是以天为单位的。

#3


66  

Outdated! See below...

过时的!见下文……

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

性能差异再怎么强调都不为过……时间是C,时间是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)

Update (2/2012):

更新(2/2012):

As already mentioned in the comment, 1.9.3 has vastly improved DateTime performance:

正如评论中已经提到的,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)

#4


42  

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.

我认为“有什么不同”的答案是Ruby标准库中这个问题的一个不幸的常见答案:两个类/libs是由不同的人在不同的时间创建的。与精心计划的Java开发相比,这是Ruby进化的社区性质的不幸后果之一。开发人员想要新的功能,但又不想涉足现有的api,因此他们只创建了一个新类——对于最终用户来说,这两个类的存在没有明显的理由。

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.

一般来说,这对软件库是正确的:一些代码或API的原因往往是历史的,而不是逻辑的。

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.

诱惑在于从DateTime开始,因为它看起来更通用。日期……和时间,对吧?错了。时间也可以更好地处理日期,实际上可以解析DateTime不能解析的时区。也表现得更好。

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)

为了安全起见,我倾向于允许将DateTime参数传递到我的Timey api中,或者转换。如果我知道两者都有我感兴趣的方法,我接受其中任何一种,就像我编写的将时间转换为XML(用于XMLTV文件)的方法一样

# 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

#5


9  

I found such things like parsing and calculating the beginning/end of a day in different timezones are easier to do with DateTime, assuming you are using the ActiveSupport extensions.

我发现,如果您使用的是ActiveSupport扩展,那么在不同时区解析和计算一天的开始/结束之类的事情更容易处理DateTime。

In my case I needed to calculate the end of the day in a user's timezone (arbitrary) based on the user's local time which I received as a string, e.g. "2012-10-10 10:10 +0300"

在我的例子中,我需要根据用户的本地时间计算用户的时区(任意)一天的结束时间,我将用户的本地时间作为字符串接收,例如。“2012-10-10 10:10 + 0300”

With DateTime it's as simple as

有了DateTime,它就变得很简单了

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

Now let's try it the same way with Time:

现在让我们用同样的方法来研究时间:

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.

Actually, Time needs to know the timezone before parsing (also note it's Time.zone.parse, not Time.parse):

实际上,时间需要在解析之前知道时区(还要注意它是Time.zone)。解析,不是Time.parse):

irb(main):044:0> Time.zone = 'EET'
=> "EET"
irb(main):045:0> Time.zone.parse('2012-10-10 10:10 +0300').end_of_day
=> Wed, 10 Oct 2012 23:59:59 EEST +03:00

So, in this case it's definitely easier to go with DateTime.

因此,在这种情况下,使用DateTime无疑更容易。

#6


4  

Consider how they handle timezones differently with custom instantiations:

考虑一下它们如何以不同的自定义实例来处理时区:

irb(main):001:0> Time.new(2016,9,1)
=> 2016-09-01 00:00:00 -0400
irb(main):002:0> DateTime.new(2016,9,1)
=> Thu, 01 Sep 2016 00:00:00 +0000
irb(main):003:0> Time.new(2016,9,1).to_i
=> 1472702400
irb(main):004:0> DateTime.new(2016,9,1).to_i
=> 1472688000

This can be tricky when creating time ranges, etc.

这在创建时间范围时可能会很棘手。

#7


0  

It seems that in some cases the behavior is very different:

似乎在某些情况下,人们的行为非常不同:

Time.parse("Ends from 28 Jun 2018 12:00 BST").utc.to_s

"2018-06-28 09:00:00 UTC"

“2018-06-28 09:00:00 UTC”

Date.parse("Ends from 28 Jun 2018 12:00 BST").to_time.utc.to_s

"2018-06-27 21:00:00 UTC"

“2018-06-27 21:00:00 UTC”

DateTime.parse("Ends from 28 Jun 2018 12:00 BST").to_time.utc.to_s

"2018-06-28 11:00:00 UTC"

“2018-06-28 11:00:00 UTC”