Ruby 迭代日期以查找日期之间的天数

Ruby 迭代日期以查找日期之间的天数,ruby,date,methods,Ruby,Date,Methods,我有一个日期数组,我需要让每个日期计算出下一个日期之间的差异,例如 a= {1=>03-01-2015, 2=>03-10-2015, 3=>03-15-2015, 4=>03-27-2015} 一个完整的对象看起来像这样 #<Transaction:0xc413c58 @id="KYYEZEPedacrwBkpqDk8C5Yy04BqvJIXJdYXJ", @account="Ppp575Ke19T8PxrAdMrNUq4Ox4AQVrHMLa5D0", @da

我有一个日期数组,我需要让每个日期计算出下一个日期之间的差异,例如

a= {1=>03-01-2015, 2=>03-10-2015, 3=>03-15-2015, 4=>03-27-2015}
一个完整的对象看起来像这样

#<Transaction:0xc413c58 @id="KYYEZEPedacrwBkpqDk8C5Yy04BqvJIXJdYXJ", @account="Ppp575Ke19T8PxrAdMrNUq4Ox4AQVrHMLa5D0", @date="2013-10-23", @amount=100, @name="COMED", @meta={"is_risky"=>false, "location"=>{"store_number"=>"10782"}}, @location=nil, @pending=false, @score={"location"=>{}, "name"=>0.2}, @type={"primary"=>"unresolved"}, @category=nil, @category_id=nil>] 
这是我到目前为止所拥有的

@collect_transactions = (@user.transactions.find_all { |t| t.name == 'due_at' })
@date_difference = @collect_transactions.map(&:date).each_cons(2) { |a,b| b-a }
我不确定每种方法是否正确,但我现在的回答是

NoMethodError: undefined method `-' for "2015-01-15":String
这不算日子……任何建议都将不胜感激

是的,这是一条路要走。您只需首先将日期字符串转换为日期对象。你可以这样做

代码

require 'date'

def date_diffs(h)    
  h.values.
    map { |s| Date.strptime(s,'%m-%d-%Y') }.
    each_cons(2).
    map { |d1,d2| (d2-d1).to_i }
end
h = { 1=>"03-01-2015", 2=>"03-10-2015", 3=>"03-15-2015", 4=>"03-27-2015" }

date_diffs(h)
  #=> [9, 5, 12]
示例

require 'date'

def date_diffs(h)    
  h.values.
    map { |s| Date.strptime(s,'%m-%d-%Y') }.
    each_cons(2).
    map { |d1,d2| (d2-d1).to_i }
end
h = { 1=>"03-01-2015", 2=>"03-10-2015", 3=>"03-15-2015", 4=>"03-27-2015" }

date_diffs(h)
  #=> [9, 5, 12]
讨论

从对问题的编辑中,您可能需要使用日期格式字符串
“%Y-%m-%d”
。另一种选择是使用而不是使用。(我通常更喜欢
strtime
,因为它要求更高。)

当然,您必须确保哈希值的顺序正确。如果您使用的是Ruby 1.9之前的版本(当时无法保证散列键的顺序,甚至无法保证键顺序的概念),或者您使用的是更新的版本(其中保留了键插入顺序),但不确定键的顺序,则可以将此作为第一步:

values = h.values_at(*(1..4))
  #=> ["03-01-2015", "03-10-2015", "03-15-2015", "03-27-2015"] 
解释

我们有:

b = h.values
  #=> ["03-01-2015", "03-10-2015", "03-15-2015", "03-27-2015"] 
c = b.map { |s| Date.strptime(s,'%m-%d-%Y') }
  #=> [#<Date: 2015-03-01 ((2457083j,0s,0n),+0s,2299161j)>,
  #    #<Date: 2015-03-10 ((2457092j,0s,0n),+0s,2299161j)>,
  #    #<Date: 2015-03-15 ((2457097j,0s,0n),+0s,2299161j)>,
  #    #<Date: 2015-03-27 ((2457109j,0s,0n),+0s,2299161j)>] 
d = c.each_cons(2)
  #=> #<Enumerator: [#<Date: 2015-03-01....
我们计算有理数:

d2-d1 #=> (9/1)
我们可以将其转换为整数(因为它总是一个整数):

(9/1).to_i #=> 9
因此,我们得到:

d.map { |d1,d2| (d2-d1).to_i }   
  #=> [9, 5, 12] 

为什么返回的是有理数而不是整数@Stefan给出了一个很好的解释。

根据日期的格式是
mm dd YYYY
还是
YYYY mm dd
(在您的问题中有点模棱两可),您可以使用Rails帮助器转换为
日期
对象。(这只适用于后者。)


不管是哪种方式,您都可能希望重构代码,将日期作为适当的日期数据类型存储在数据库中。

请告诉我。进一步的操作可以使用
transaction|dates.map{transaction|Date.parse(transaction.Date)}.each|cons(2).map{a,b |(b-a).为了{i}
仍然得到一个错误,我已经更新了这个问题,以显示数组中完整对象的外观,也许这是导致问题的原因,非常好,谢谢您的详细解释!这个问题有些含糊不清。首先,您说您有一个日期的
数组
,但显示一个
散列
。此外,问题中混合了两种不同的日期格式。请把这些整理一下,以帮助我们给出更准确的答案。
a.map { |t| t.date.to_date }.each_cons(2).map { |a, b| (b - a).to_i }