我有一个Time对象T.什么是将N天添加到T的合理方法?
我提出的最好的感觉有点折磨:
require 'date'
def add_days(time, days)
time.to_date.next_day(days).to_time
end
P.S。:如果您在美国,正确的答案必须满足:
add_days(Time.new(2013, 3, 10, 0), 1) == Time.new(2013, 3, 11, 0)
如果您在欧盟,正确的答案必须满足:
add_days(Time.new(2013, 3, 31, 0), 1) == Time.new(2013, 4, 1, 0)
P.P.S:这是一个Ruby问题,而不是Rails问题。
答案 0 :(得分:9)
Time
有+
method,接受秒数。
N = 3
t = Time.now + N * 86400 # 24 * 60 * 60
或者,如果您携带ActiveSupport,则更容易
require 'active_support/core_ext'
t = Time.now + N.days
你显然可以自己做帮手
class Fixnum
def days
self * 86400
end
end
t = Time.now # => 2013-01-31 16:06:31 +0700
t + 3.days # => 2013-02-03 16:06:31 +0700
答案 1 :(得分:6)
似乎已成为我的风格,我正在回答我自己的问题。
由于跨越DST / ST的过渡相当罕见(并且在世界的许多地方都不存在),更有效的方法是首先添加(n_days * 24 * 60 * 60)秒,然后检查UTC偏移量已经改变。如果有,则创建更正的时间对象。
像这样:
def add_days(time, n_days)
t2 = time + (n_days * 24 * 60 * 60)
utc_delta = time.utc_offset - t2.utc_offset
(utc_delta == 0) ? t2 : t2 + utc_delta
end
这种方法可以避免大量额外的对象创建,并且可以正确处理夏令时的转换(至少在我当前的时区,太平洋时间):
>> t1 = Time.new(2013, 3, 10, 0, 0, 0)
=> 2013-03-10 00:00:00 -0800 # midnight Mar 3, 2013 Pacific Standard Time
>> t2 = add_days(t1, 1)
=> 2013-03-11 00:00:00 -0700 # midnight Mar 4, 2013 Pacific Daylight Time
>> t2 - t1
=> 82800.0 # a shorter than usual day
>> u1 = Time.new(2013, 11, 3, 0, 0, 0)
=> 2013-11-03 00:00:00 -0700 # midnight Nov 3, 2013 Pacific Daylight Time
>> u2 = add_days(u1, 1)
=> 2013-11-04 00:00:00 -0800 # midnight Nov 4, 2013 Pacific Standard Time
>> u2 - u1
=> 90000.0 # a longer than usual day
答案 2 :(得分:5)
ActiveSupport::TimeWithZone似乎处理得很好
> t1 = ActiveSupport::TimeZone['Eastern Time (US & Canada)'].parse('2013-03-10')
=> Sun, 10 Mar 2013 00:00:00 EST -05:00
注意下面的类类型:
> t1.class
=> ActiveSupport::TimeWithZone
请注意以上从EST到EDT的变化:
> t1 + 1.day
=> Mon, 11 Mar 2013 00:00:00 EDT -04:00
答案 3 :(得分:1)
这有点侧面回答但是因为在你原来的问题中你不关心Time
的HMS部分,你最好不要使用Date
对象吗?
require 'date'
t=Time.now
d=Date.parse(t.to_s)
puts d+1 # => gives you tomorrow's day (YMD)
修改:添加require 'date'
以提高答案的全面性,如评论部分所述。