微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

计算两个日期之间有多少 n.month 问:start_date + n.months >= end_dates,变量n是什么?

如何解决计算两个日期之间有多少 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_difftime_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 对象 date1date2 之间的差异,其中 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 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?