【问题标题】:Calculate days between two dates [always keeping months of max 30 days]计算两个日期之间的天数 [始终保持最多 30 天的月份]
【发布时间】:2020-06-05 01:40:16
【问题描述】:

假设每个月都有 30 天,我想计算两个给定日期之间的天数。

FROM 05/04/2020
TO   20/12/2020

result: 256 days (NOT 259 days if we considered months with 31 days)

通过日期之间的简单数学减法,我得到了错误的结果:

(Date.new(2019,12,20) - Date.new(2019,4,5)).floor
=> 259

为了克服这个问题,我必须创建一个非常复杂的算法:

    days += inclusive_days_in_range(
      position_data[:workFrom],
      position_data[:workFrom].at_end_of_month
    )

    months = inclusive_months_in_range(
      position_data[:workFrom].at_beginning_of_month.next_month,
      position_data[:workTo].at_end_of_month.prev_month
    )
    days += months * MAX_DAYS_IN_MONTHS

    days += inclusive_days_in_range(
      position_data[:workTo].at_beginning_of_month,
      position_data[:workTo]
    )

有简单的方法吗?

【问题讨论】:

  • 我既震惊又着迷,您的要求是正确的日历感知计算是“错误的结果”
  • @Max 一些计算使用所谓的30/360 day count convention。

标签: ruby


【解决方案1】:

类似于@CarySwoveland 的回答,但使用点积:

require 'matrix'

def ndays str
  Vector[*str.split('/').map(&:to_i)].dot [1,30,360]
end

> ndays('20/12/2020') - ndays('05/04/2020') + 1
=> 256

添加+1,因为您似乎想要天数,包括天数。

【讨论】:

    【解决方案2】:

    另一种方法是计算月数,乘以 30,然后将天数减去 FROM 日期的月份,并加上 TO 日期的天数。

    这里的堆栈溢出问题已经得到解答:Find number of months between two Dates in Ruby on Rails

    所以我将使用它作为获取月份的参考。然后就是加减法了

    from_date = Date.new(2019,4,5)
    to_date = Date.new(2019,12,20)
    num_months = (12*(to_date.year-from_date.year))+(to_date.month-from_date.month)
    
    # We add 1 to make it inclusive, otherwise you get 255
    num_days = (num_months*30) + to_date.day - from_date.day + 1 
    

    【讨论】:

    • 谢谢杰西,我喜欢这个解决方案
    【解决方案3】:
    def days_from_zero(date_str)
      d, m, y = date_str.split('/').map(&:to_i)
      d + 30*(m + 12*y)
    end
    

    days_from_zero("05/04/2020") - days_from_zero("4/04/2020")  #=> 1 
    days_from_zero("20/12/2020") - days_from_zero("05/04/2020") #=> 255 
    days_from_zero("05/04/2020") - days_from_zero("20/12/2020") #=> -255 
    days_from_zero("05/04/2020") - days_from_zero("3/6/20")     #=> 719942 
    

    【讨论】:

    • 阿布鲁斯坎历有 30 天的月份。例如,今天是 2020 年 2 月 25 日,阿布鲁斯坎。更正为与每个世纪初的公历一致。 2000 年 12 月 31 日(公历),也就是最后一次更正的前一天,是 1998 年 9 月 10 日(阿布鲁斯坎)。根据 Wiki,全世界有超过 1 亿人口使用阿布鲁斯坎历。在 Ruby v2.8 中,方法将被添加到 Ruby 的 Date 类中以支持 Abruscan 日历(例如,Date#to_abruscan 和 Date::parse_abruscan)。
    猜你喜欢
    • 2016-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-28
    • 2022-01-19
    • 2019-04-12
    相关资源
    最近更新 更多