如何检查两个日期之间的差异是否恰好是X个月的倍数

时间:2017-01-31 14:00:20

标签: ruby-on-rails ruby

我有两个日期(Date对象)。我需要检查两者之间的差异是否恰好是X个月的倍数(考虑几个月的天数和最后几天)。

为简单起见,我们假设这个问题的X值为4。

我想要实现的最简单的逻辑是以下几点(只有FOUR_MONTHS不起作用,因为modulo似乎只适用于整数)。所以,我想知道是否有任何方式(我可能只是错过了)来模仿以下内容:

(Date.parse('2017-01-15') - Date.parse('2016-09-15')) % (FOUR_MONTHS) == 0
(Date.parse('2017-01-15') - Date.parse('2016-09-14')) % (FOUR_MONTHS) != 0
(Date.parse('2017-01-15') - Date.parse('2016-05-15')) % (FOUR_MONTHS) == 0
(Date.parse('2017-01-31') - Date.parse('2016-09-30')) % (FOUR_MONTHS) == 0
(Date.parse('2016-11-30') - Date.parse('2016-07-31')) % (FOUR_MONTHS) == 0
(Date.parse('2016-11-30') - Date.parse('2016-07-30')) % (FOUR_MONTHS) == 0

目前,我可以考虑循环每个FOUR_MONTHS,但我认为它不会有效,而且可能有一种更简单的方法,或者我可能错过了一个非常简单的Ruby方法。 / p>

P.S。我用ruby-on-rails标记了这个问题,因为ActiveSupport::TimeZone可能与实现存在差异。

4 个答案:

答案 0 :(得分:1)

这应该适用于Rails(需要end_of_month):

def month_id(date)
  date.month + date.year * 12
end

def same_day?(date1, date2)
  (last_day_of_month?(date1) && date2.day >= date1.day) ||
  (last_day_of_month?(date2) && date1.day >= date2.day) ||
  date1.day == date2.day
end

def last_day_of_month?(date)
  date == date.end_of_month
end

def separated_by_multiple_of_x_months?(date1, date2, x = 4)
  same_day?(date1, date2) && (month_id(date1) - month_id(date2)) % x == 0
end

separated_by_multiple_of_x_months?(Date.parse('2017-01-15'), Date.parse('2016-09-15'))
#=> true
separated_by_multiple_of_x_months?(Date.parse('2017-01-15'), Date.parse('2016-09-14'))
#=> false
separated_by_multiple_of_x_months?(Date.parse('2017-01-15'), Date.parse('2016-05-15'))
#=> true
separated_by_multiple_of_x_months?(Date.parse('2017-01-31'), Date.parse('2016-09-30'))
#=> true
separated_by_multiple_of_x_months?(Date.parse('2016-11-30'), Date.parse('2016-07-31'))
#=> true
separated_by_multiple_of_x_months?(Date.parse('2016-11-30'), Date.parse('2016-07-30'))
#=> true

答案 1 :(得分:0)

您可以尝试(end_date - start_date % x * (30.days / 1.day)).to_i.zero?

之类的内容

答案 2 :(得分:0)

如果您执行了to_i,那么您将获得天数差异:

(Date.parse('2017-01-15') - Date.parse('2016-09-15')).to_i

答案 3 :(得分:0)

好的第二次尝试。您可以使用ActiveSupport的months_agomonths_since方法:

假设date1小于date2:

def months_apart?(date1, date2, num_of_months)
  date2.months_ago(num_of_months) == date1
end