arraysrubyalgorithmdatedate-difference

How to write an algorithm that count the duration of time without repetitions


We have an array of date interval arrays: [[start_date, end_date], [], ...] For example:

    [ 
      [01.02.2020, 01.05.2020], # 3 months
      [01.01.2020, 01.10.2020], # 9 month, but we cant count the time already in the array, so 6 month
      ...
    ]

As a result of executing the algorithm, we should get the number of days/months/years of the duration of the period. How do i write this? I'll be grateful for your help


Solution

  • For the number of days the task can be solved quite easily:

    So:

    input = [["01.02.2020", "01.05.2020"],["01.01.2020", "01.10.2020"]]
    
    days =
      input
        .map { |start_date, end_date| Date.parse(start_date)..Date.parse(end_date) }
        .map(&:to_set)
        .reduce(&:union)
    

    (can be done more concisely; leaving this for you)

    This gives you an accurate number of days (days.size), without duplicates lying in the ranges' intersections. But getting to month/years is a bit more tricky. Ok, maybe not tricky per se, but it needs some extra clarification on how to calculate partially covered months/years (for example, is it ok or not to calculate last 2 weeks of August and first 2 weeks of September as 1 month). For the simplest case it may be as simple as dividing days by 30 to get months and by 360 to get years (but the rules might be way more sophisticated).