Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect if dates are consecutive in Rails?

I'm looking to check for consecutive dates and display them differently if they are consecutive.

I'm working with Garage Sales that have multiple dates per sale. I'd like to then cycle through each date, and group any consecutive dates to display as a group: Ex: Apr 28 - Apr 30

I also need to account for non-consecutive dates: Ex: Apr 15, Apr 28 - 30

Additionally, weekly dates need to be recognized as non-consecutive (so basically avoid step checks): Ex: Apr 16, Apr 23, Apr 30


So far, I'm taking each date that hasn't passed & ordering them properly.

garage_sale_dates.where("date > ?",Time.now).order(:date)

Thanks for any help! Let me know if any other info is needed.

like image 485
Pandy Avatar asked Mar 13 '23 11:03

Pandy


1 Answers

You can use the slice_before method of Enumerable

dates = [Date.yesterday, Date.today, Date.tomorrow, Date.parse('2016-05-01'), Date.parse('2016-05-02'), Date.parse('2016-05-05')]
# => [Wed, 27 Apr 2016, Thu, 28 Apr 2016, Fri, 29 Apr 2016, Sun, 01 May 2016, Mon, 02 May 2016, Thu, 05 May 2016]

prev = dates.first
dates.slice_before { |d| prev, prev2 = d, prev; prev2 + 1.day != d }.to_a
# => [[Wed, 27 Apr 2016, Thu, 28 Apr 2016, Fri, 29 Apr 2016], [Sun, 01 May 2016, Mon, 02 May 2016], [Thu, 05 May 2016]]

Then you can simply join the 2-or-more-element arrays from the result with "-", and leave the single element arrays intact:

prev = dates.first
dates.slice_before { |d| prev, prev2 = d, prev; prev2 + 1.day != d }.
      map{|d| d.size > 1 ? "#{d.first.to_s} - #{d.last.to_s}" : d.first.to_s }
# => ["2016-04-27 - 2016-04-29", "2016-05-01 - 2016-05-02", "2016-05-05"]

There is even a commented example in the docs that is technically equivalent to yours (but deals with integers, not dates).

like image 52
Matouš Borák Avatar answered Apr 01 '23 04:04

Matouš Borák