Ruby中的DateTime和Time类之间有什么区别,是什么因素导致我选择其中一个?
当前回答
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.
一般来说,对于软件库来说,这是正确的:一些代码或API之所以是这样,往往是历史原因,而不是逻辑原因。
我们倾向于从DateTime开始,因为它看起来更通用。日期……还有时间,对吧?错了。Time在日期方面也做得更好,实际上它可以解析DateTime不能解析的时区。它的性能也更好。
我在任何地方都使用时间。
不过为了安全起见,我倾向于允许将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
其他回答
考虑一下它们在自定义实例化时处理时区的不同方式:
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
在创建时间范围等时,这可能很棘手。
我发现,如果使用ActiveSupport扩展,使用DateTime可以更容易地解析和计算不同时区的一天开始/结束时间。
在我的情况下,我需要计算一天的结束在一个用户的时区(任意)基于用户的本地时间,我接收到一个字符串,例如。"2012-10-10 10:10 +0300"
使用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
现在让我们以同样的方式来尝试《时间》:
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.
实际上,Time在解析之前需要知道时区(还要注意它是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
在这种情况下,使用DateTime显然更容易。
除了尼尔斯·甘瑟的回答,你可以考虑以下论点:
请注意,Ruby风格指南非常清楚地说明了这一点:
No DateTime Don’t use DateTime unless you need to account for historical calendar reform - and if you do, explicitly specify the start argument to clearly state your intentions. # bad - uses DateTime for current time DateTime.now # good - uses Time for current time Time.now # bad - uses DateTime for modern date DateTime.iso8601('2016-06-29') # good - uses Date for modern date Date.iso8601('2016-06-29') # good - uses DateTime with start argument for historical date DateTime.iso8601('1751-04-23', Date::ENGLAND)
似乎在某些情况下,行为是非常不同的:
Time.parse("Ends from 28 Jun 2018 12:00 BST").utc.to_s
"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”
DateTime.parse("Ends from 28 Jun 2018 12:00 BST").to_time.utc.to_s
“2018-06-28 11:00:00 utc”
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.
一般来说,对于软件库来说,这是正确的:一些代码或API之所以是这样,往往是历史原因,而不是逻辑原因。
我们倾向于从DateTime开始,因为它看起来更通用。日期……还有时间,对吧?错了。Time在日期方面也做得更好,实际上它可以解析DateTime不能解析的时区。它的性能也更好。
我在任何地方都使用时间。
不过为了安全起见,我倾向于允许将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
推荐文章
- 是否可以在MiniTest中运行单个测试?
- 如何在Ruby中生成a和b之间的随机数?
- 解析日期字符串并更改格式
- 无法安装gem -未能建立gem本地扩展-无法加载这样的文件——mkmf (LoadError)
- 如何在Ruby中创建文件
- 在Java中转换字符串到日历对象
- 什么是Ruby文件。开放模式和选项?
- Ruby数组到字符串的转换
- 如何分割(块)一个Ruby数组成X元素的部分?
- Ruby中“or”和||的区别?
- ZoneOffset之间的区别是什么。UTC和ZoneId.of(“UTC”)?
- 如何检查DST(日光节约时间)是否有效,如果是,偏移量?
- 如何测试参数是否存在在轨道
- 单元测试:日期时间。现在
- 如何解析unix时间戳到时间。时间