gpt4 book ai didi

ruby-on-rails - (Time.now.utc.to_date + 1.month + 15.days) != (Time.now.utc.to_date + 15.days + 1.month)

转载 作者:数据小太阳 更新时间:2023-10-29 07:21:00 25 4
gpt4 key购买 nike

这怎么可能?

Time.now.utc.to_date + 1.month + 15.days #=> Mon, 01 Dec 2014
Time.now.utc.to_date + 15.days + 1.month #=> Sun, 30 Nov 2014

有人看过吗?

/编辑

我想我问错了问题。那你们怎么解释呢?

Time.now.utc.to_date + (15.days + 1.month) #=> Mon, 08 Dec 2014
Time.now.utc.to_date + (1.month + 15.days) #=> Tue, 09 Dec 2014

(15.days + 1.month) #=> 3888000
(1.month + 15.days) #=> 3888000

最佳答案

首先让我们看看 Integer#month ,它返回一个 ActiveSupport::Duration 的实例。在 Rails 控制台:

~/rails/rfinan (1296000):1 > elapsed = 1.month
=> 2592000
~/rails/rfinan (1296000):1 > elapsed.value
=> 2592000
~/rails/rfinan (1296000):1 > elapsed.parts
=> [[:months,1]]
~/rails/rfinan (1296000):1 > elapsed.is_a? ActiveSupport::Duration
=> true

该方法了:ActiveSupport::Duration#+

~/rails/rfinan (1296000):1 > sum1 = 1.month + 15.days
=> 3888000
~/rails/rfinan (1296000):1 > sum2 = 15.days + 1.month
=> 3888000
~/rails/rfinan (1296000):1 > sum1.value
=> 3888000
~/rails/rfinan (1296000):1 > sum1.parts
=> [[:months,1],[:days,15]]
~/rails/rfinan (1296000):1 > sum2.value
=> 3888000
~/rails/rfinan (1296000):1 > sum2.parts
=> [[:days,15],[:months,1]]
~/rails/rfinan (1296000):1 > sum1 == sum2
=> true
~/rails/rfinan (1296000):1 > sum1.value == sum2.value
=> true
~/rails/rfinan (1296000):1 > sum1.parts == sum2.parts
=> false

现在是 Date#+ ,ActiveSupport 版本。

def plus_with_duration(other) #:nodoc:
if ActiveSupport::Duration === other
other.since(self)
else
plus_without_duration(other)
end
end
alias_method :plus_without_duration, :+
alias_method :+, :plus_with_duration

这意味着:如果我将 :+ 发送到带有 ActiveSupport::Duration 实例作为参数的 Date 实例,它会调用 ActiveSupport::Duration#since ,最后一个调用 ActiveSupport::Duration#sum ,它会注入(inject)日期实例,并在每个实例上调用 Date#advance部分持续时间实例:

  def sum(sign, time = ::Time.current) #:nodoc:
parts.inject(time) do |t,(type,number)|
if t.acts_like?(:time) || t.acts_like?(:date)
if type == :seconds
t.since(sign * number)
else
t.advance(type => sign * number)
end
else
raise ::ArgumentError, "expected a time or date, got #{time.inspect}"
end
end
end

记住 sum1.parts != sum2.parts?, sum 按顺序发送到日期实例。让我们看看 Date#advance 是什么意思

def advance(options)
options = options.dup
d = self
d = d >> options.delete(:years) * 12 if options[:years]
d = d >> options.delete(:months) if options[:months]
d = d + options.delete(:weeks) * 7 if options[:weeks]
d = d + options.delete(:days) if options[:days]
d
end

当提前收到 month: 1 时,它从 stdlib 调用 Date#>>,其工作方式与 ActiveSupport::Duration#+ 不同。在 irb:

~ (main) > Date.new(2014,10,31) >> 1
=> #<Date: 2014-11-30 ((2456992j,0s,0n),+0s,2299161j)>
~ (main) > Date.new(2014,10,31) >> 2
=> #<Date: 2014-12-31 ((2457023j,0s,0n),+0s,2299161j)>
~ (main) > Date.new(2014,10,31) >> 3
=> #<Date: 2015-01-31 ((2457054j,0s,0n),+0s,2299161j)>
~ (main) > Date.new(2014,10,31) >> 4
=> #<Date: 2015-02-28 ((2457082j,0s,0n),+0s,2299161j)>
~ (main) > Date.new(2014,10,31) >> 5
=> #<Date: 2015-03-31 ((2457113j,0s,0n),+0s,2299161j)>
~ (main) > Date.new(2014,10,31) >> 12
=> #<Date: 2015-10-31 ((2457327j,0s,0n),+0s,2299161j)>
~ (main) > Date.new(2014,10,31) >> 1200
=> #<Date: 2114-10-31 ((2493486j,0s,0n),+0s,2299161j)>
~ (main) > Date.new(2014,10,31) >> 12000
=> #<Date: 3014-10-31 ((2822204j,0s,0n),+0s,2299161j)>

很明显 Date#>> 不添加天数,添加月份并保留天数。如果该日期对目标月份无效,则会修复它。添加固定的月数并不能固定添加的天数,因为这取决于开始日期。

现在我们可以说 Date#+ 与 ActiveSupport::Duration#+ 不同,我们知道原因。

答案是使用 ActiveSupport::Duration 实例调用的 Date#+(比如持续时间)不关心 duration.value,它使用 duration.parts,这在每种情况下都是不同的。

关于ruby-on-rails - (Time.now.utc.to_date + 1.month + 15.days) != (Time.now.utc.to_date + 15.days + 1.month),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26408585/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com