如何解决计算两个日期之间有多少 n.month 问:start_date + n.months >= end_dates,变量n是什么?
我想按月计算两个日期之间的距离:
问:start_date + n.months >= end_dates,变量n是什么?
start_date = Date.parse('2021-01-31')
end_date = Date.parse('2021-02-28')
## start_date + 1.months = 2021-02-28
## The answer 1 month,which is more clearable for human using
## Don't want to find the answer like 28 days or 0.93 month. (30 day a month)
首先我试图让每个月是 30.days,但答案会在某些特殊日期上有一些偏差。每个月的日期都不同,End of Feb month
上的日期始终是问题所在。
然后我尝试安装像 date_diff
、time_difference
... 这样的 gem,但是没有任何方法可以做到这一点,大部分输出是 28 天而不是 1 个月。
对于简单的方法,我可以轻松地进行迭代循环来找到 n
,例如:
start_date = Date.parse('2021-01-31')
end_date = Date.parse('2021-02-28')
def calc_diff(start_date,end_date)
n = 0
while start_date + n.months < end_date
n += 1
end
n
end
有没有更好的方法可以找到两个日期之间的 n
个月,而不是使用循环?
谢谢。
解决方法
我对问题的理解与以下示例一致。我已经计算了 Date
对象 date1
和 date2
之间的差异,其中 date2 >= date1
。
require 'date'
def months_between(date1,date2)
12*(date2.yr - date1.yr) + date2.mon - date1.mon + date2.day > date1.day ? 1 : 0
end
months_between Date.new(2020,1,22),Date.new(2020,3,21) #=> 2
months_between Date.new(2020,22) #=> 2
months_between Date.new(2020,23) #=> 3
months_between Date.new(2020,Date.new(2021,21) #=> 14
months_between Date.new(2020,22) #=> 14
months_between Date.new(2020,23) #=> 15
,
# find minimum n so that `start_date + n.months >= end_dates`
def calc_diff(start_date,end_date)
diff = (end_date.yday - start_date.yday) / 30
return diff if start_date + diff.months >= end_date
diff + 1
end
calc_diff(Date.parse('2021-01-31'),Date.parse('2021-02-28')) # 1
calc_diff(Date.parse('2021-01-31'),Date.parse('2021-04-30')) # 3
calc_diff(Date.parse('2021-01-31'),Date.parse('2021-05-31')) # 4
calc_diff(Date.parse('2021-02-01'),Date.parse('2021-06-01')) # 4
calc_diff(Date.parse('2021-02-01'),Date.parse('2021-06-02')) # 5
,
感谢@Cary 和@Lam 的回答。
这是我找到 n month
的答案。
# try to find the minimum n month between start_date and target_date
def calc_diff(start_date,target_date)
months_diff = (target_date.year * 12 + target_date.month) - (start_date.year * 12 + start_date.month)
## need to check the end of month because some special case
## start date: 2020-01-31 ; end date 2020-06-30
## the minimum n month must be 5
## another special case of Feb must consider (test case 15)
if start_date.day > target_date.day && !((start_date == start_date.end_of_month || target_date.month == 2) && (target_date == target_date.end_of_month))
months_diff = months_diff - 1
end
puts months_diff # it will show the minimum whole n month
# the target_date will between inside
# (start_date + months_diff.months) <= target_date < (start_date + (months_diff + 1).months)
(start_date + months_diff.months)..(start_date + (months_diff + 1).months)
end
测试用例:
## test case 1
## 6/15 - 7/15 => n = 5
calc_diff(Date.parse('2020-01-15'),Date.parse('2020-06-19'))
## test case 2
## 7/15 - 8/15 => n = 6
calc_diff(Date.parse('2020-01-15'),Date.parse('2020-07-15'))
## test case 3
## 5/15 - 6/15 => n = 4
calc_diff(Date.parse('2020-01-15'),Date.parse('2020-06-01'))
## test case 4 (special case)
## 6/30 - 7/31 => n = 5
calc_diff(Date.parse('2020-01-31'),Date.parse('2020-06-30'))
## test case 5
## 7/30 - 8/30 => n = 4
calc_diff(Date.parse('2020-04-30'),Date.parse('2020-07-31'))
## test case 6
## 6/30 - 7/30 => n = 2
calc_diff(Date.parse('2020-04-30'),Date.parse('2020-06-30'))
## test case 7
## 5/31 - 6/30 => n = 4
calc_diff(Date.parse('2020-01-31'),Date.parse('2020-05-31'))
## test case 8
## 2/29 - 3/31 => n = 1
calc_diff(Date.parse('2020-01-31'),Date.parse('2020-02-29'))
## test case 9
## 6/29 - 7/29 => n = 4
calc_diff(Date.parse('2020-02-29'),Date.parse('2020-06-30'))
## test case 10
## 7/29 - 8/29 => n = 5
calc_diff(Date.parse('2020-02-29'),Date.parse('2020-07-31'))
## test case 11
## 1/31 - 2/29 => n = 0
calc_diff(Date.parse('2020-01-31'),Date.parse('2020-02-28'))
## test case 12
## 2/29 - 3/31 => n = 1
calc_diff(Date.parse('2020-01-31'),Date.parse('2020-03-01'))
## test case 13
## 1/17 - 2/17 => n = 0
calc_diff(Date.parse('2020-01-17'),Date.parse('2020-01-17'))
## test case 14
## 1/17 - 2/17 => n = 0
calc_diff(Date.parse('2020-01-17'),Date.parse('2020-01-18'))
## test case 15 (special case)
## 1/30 - 2/29 => n = 1
calc_diff(Date.parse('2019-12-30'),Date.parse('2020-02-28'))
## test case 16
## 2/29 - 3/30 => n = 2
calc_diff(Date.parse('2019-12-30'),Date.parse('2020-02-29'))
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。