如何添加N天到时间T(占夏令时)?

时间:2013-01-31 09:00:30

标签: ruby time

我有一个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问题。

4 个答案:

答案 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'以提高答案的全面性,如评论部分所述。