Reputation: 19
My array is generated by the
start_date = (Date.today + 10.hours + 30.minutes).to_datetime
end_date = (Date.today + 1.day + 18.hours).to_datetime
period = 0.5/24
array = start_date.step(end_date, period).to_a
this is the result (but this result is going to cover max 62 days)
array =
[Sat, 25 Feb 2023 10:30:00 +0000, Sat, 25 Feb 2023 11:00:00 +0000, Sat, 25 Feb 2023 11:30:00 +0000,
Sat, 25 Feb 2023 12:00:00 +0000, Sat, 25 Feb 2023 12:30:00 +0000, Sat, 25 Feb 2023 13:00:00 +0000,
Sat, 25 Feb 2023 13:30:00 +0000, Sat, 25 Feb 2023 14:00:00 +0000, Sat, 25 Feb 2023 14:30:00 +0000,
Sat, 25 Feb 2023 15:00:00 +0000, Sat, 25 Feb 2023 15:30:00 +0000, Sat, 25 Feb 2023 16:00:00 +0000,
Sat, 25 Feb 2023 16:30:00 +0000, Sat, 25 Feb 2023 17:00:00 +0000, Sat, 25 Feb 2023 17:30:00 +0000,
Sat, 25 Feb 2023 18:00:00 +0000, Sat, 25 Feb 2023 18:30:00 +0000, Sat, 25 Feb 2023 19:00:00 +0000,
Sat, 25 Feb 2023 19:30:00 +0000, Sat, 25 Feb 2023 20:00:00 +0000, Sat, 25 Feb 2023 20:30:00 +0000,
Sat, 25 Feb 2023 21:00:00 +0000, Sat, 25 Feb 2023 21:30:00 +0000, Sat, 25 Feb 2023 22:00:00 +0000,
Sat, 25 Feb 2023 22:30:00 +0000, Sat, 25 Feb 2023 23:00:00 +0000, Sat, 25 Feb 2023 23:30:00 +0000,
Sun, 26 Feb 2023 00:00:00 +0000, Sun, 26 Feb 2023 00:30:00 +0000, Sun, 26 Feb 2023 01:00:00 +0000,
Sun, 26 Feb 2023 01:30:00 +0000, Sun, 26 Feb 2023 02:00:00 +0000, Sun, 26 Feb 2023 02:30:00 +0000,
Sun, 26 Feb 2023 03:00:00 +0000, Sun, 26 Feb 2023 03:30:00 +0000, Sun, 26 Feb 2023 04:00:00 +0000,
Sun, 26 Feb 2023 04:30:00 +0000, Sun, 26 Feb 2023 05:00:00 +0000, Sun, 26 Feb 2023 05:30:00 +0000,
Sun, 26 Feb 2023 06:00:00 +0000, Sun, 26 Feb 2023 06:30:00 +0000, Sun, 26 Feb 2023 07:00:00 +0000,
Sun, 26 Feb 2023 07:30:00 +0000, Sun, 26 Feb 2023 08:00:00 +0000, Sun, 26 Feb 2023 08:30:00 +0000,
Sun, 26 Feb 2023 09:00:00 +0000, Sun, 26 Feb 2023 09:30:00 +0000, Sun, 26 Feb 2023 10:00:00 +0000,
Sun, 26 Feb 2023 10:30:00 +0000, Sun, 26 Feb 2023 11:00:00 +0000, Sun, 26 Feb 2023 11:30:00 +0000,
Sun, 26 Feb 2023 12:00:00 +0000, Sun, 26 Feb 2023 12:30:00 +0000, Sun, 26 Feb 2023 13:00:00 +0000,
Sun, 26 Feb 2023 13:30:00 +0000, Sun, 26 Feb 2023 14:00:00 +0000, Sun, 26 Feb 2023 14:30:00 +0000,
Sun, 26 Feb 2023 15:00:00 +0000, Sun, 26 Feb 2023 15:30:00 +0000, Sun, 26 Feb 2023 16:00:00 +0000,
Sun, 26 Feb 2023 16:30:00 +0000, Sun, 26 Feb 2023 17:00:00 +0000, Sun, 26 Feb 2023 17:30:00 +0000,
Sun, 26 Feb 2023 18:00:00 +0000]
From this array I want to remove all the datetimes that are between beginning of each day till 10:29 o'clock and after 18:00 o'clock till the end of each the day.
Desired result:
array =
[Sat, 25 Feb 2023 10:30:00 +0000, Sat, 25 Feb 2023 11:00:00 +0000, ....... Sat, 25 Feb 2023 18:00:00 +0000,
Sun, 26 Feb 2023 10:30:00 +0000, Sun, 26 Feb 2023 11:00:00 +0000, ....... Sun, 26 Feb 2023 18:00:00 +0000]
I'ved tried
w_start_time = (start_date + 8.hours + 1.minute).strftime('%k:%M:%S')
w_end_time = (start_date - 1.minute).strftime('%k:%M:%S')
hours = array_of_datestimes.reject! { |n| n.strftime('%k:%M:%S').between?(w_start_time, w_end_time) }
this returns nil
Can someone help me?
Thank you
Upvotes: 0
Views: 70
Reputation: 110675
Here are two ways.
Convert to minutes.
array.accept! { |date| (630..1080).cover?(60*date.hour + date.min) }
where 630 = 60*10+30
and 1080 = 60*18
. See Range#cover?, which only uses range end points, making it very efficient.
Count to determine which elements to keep
We see that on the first day we wish to keep the first
(18.0 - 10.5)/0.5 + 1 = 16
elements. As there are 48 30-minute intervals per day, we wish to remove the next
48 - 16 = 32
elements. We therefore may create an enumerator that generates false
16 times, then true
32 times, then repeats, where an element of array
is to be removed if the corresponding value of the enumerator equals true
. We can use Array#cycle to create this enumerator.
reject = ([false]*16 + [true]*32).cycle
#=> #<Enumerator: [false, false, false, false, false, false, false,
# false, false, false, false, false, false, false, false, false,
# true, true, true, true, true, true, true, true, true, true,
# true, true, true, true, true, true, true, true, true, true,
# true, true, true, true, true, true, true, true, true, true,
# true, true]:cycle>
We then simply write
array.reject! { reject.next }
To illustrate this calculation suppose array
held an array of strings corresponding to the DateTime
elements of the given array.
array = [
"Sat, 25 Feb 2023 10:30:00 +0000", "Sat, 25 Feb 2023 11:00:00 +0000",
"Sat, 25 Feb 2023 11:30:00 +0000", "Sat, 25 Feb 2023 12:00:00 +0000",
"Sat, 25 Feb 2023 12:30:00 +0000", "Sat, 25 Feb 2023 13:00:00 +0000",
"Sat, 25 Feb 2023 13:30:00 +0000", "Sat, 25 Feb 2023 14:00:00 +0000",
"Sat, 25 Feb 2023 14:30:00 +0000", "Sat, 25 Feb 2023 15:00:00 +0000",
"Sat, 25 Feb 2023 15:30:00 +0000", "Sat, 25 Feb 2023 16:00:00 +0000",
"Sat, 25 Feb 2023 16:30:00 +0000", "Sat, 25 Feb 2023 17:00:00 +0000",
"Sat, 25 Feb 2023 17:30:00 +0000", "Sat, 25 Feb 2023 18:00:00 +0000",
"Sat, 25 Feb 2023 18:30:00 +0000", "Sat, 25 Feb 2023 19:00:00 +0000",
"Sat, 25 Feb 2023 19:30:00 +0000", "Sat, 25 Feb 2023 20:00:00 +0000",
"Sat, 25 Feb 2023 20:30:00 +0000", "Sat, 25 Feb 2023 21:00:00 +0000",
"Sat, 25 Feb 2023 21:30:00 +0000", "Sat, 25 Feb 2023 22:00:00 +0000",
"Sat, 25 Feb 2023 22:30:00 +0000", "Sat, 25 Feb 2023 23:00:00 +0000",
"Sat, 25 Feb 2023 23:30:00 +0000", "Sun, 26 Feb 2023 00:00:00 +0000",
"Sun, 26 Feb 2023 00:30:00 +0000", "Sun, 26 Feb 2023 01:00:00 +0000",
"Sun, 26 Feb 2023 01:30:00 +0000", "Sun, 26 Feb 2023 02:00:00 +0000",
"Sun, 26 Feb 2023 02:30:00 +0000", "Sun, 26 Feb 2023 03:00:00 +0000",
"Sun, 26 Feb 2023 03:30:00 +0000", "Sun, 26 Feb 2023 04:00:00 +0000",
"Sun, 26 Feb 2023 04:30:00 +0000", "Sun, 26 Feb 2023 05:00:00 +0000",
"Sun, 26 Feb 2023 05:30:00 +0000", "Sun, 26 Feb 2023 06:00:00 +0000",
"Sun, 26 Feb 2023 06:30:00 +0000", "Sun, 26 Feb 2023 07:00:00 +0000",
"Sun, 26 Feb 2023 07:30:00 +0000", "Sun, 26 Feb 2023 08:00:00 +0000",
"Sun, 26 Feb 2023 08:30:00 +0000", "Sun, 26 Feb 2023 09:00:00 +0000",
"Sun, 26 Feb 2023 09:30:00 +0000", "Sun, 26 Feb 2023 10:00:00 +0000",
"Sun, 26 Feb 2023 10:30:00 +0000", "Sun, 26 Feb 2023 11:00:00 +0000",
"Sun, 26 Feb 2023 11:30:00 +0000", "Sun, 26 Feb 2023 12:00:00 +0000",
"Sun, 26 Feb 2023 12:30:00 +0000", "Sun, 26 Feb 2023 13:00:00 +0000",
"Sun, 26 Feb 2023 13:30:00 +0000", "Sun, 26 Feb 2023 14:00:00 +0000",
"Sun, 26 Feb 2023 14:30:00 +0000", "Sun, 26 Feb 2023 15:00:00 +0000",
"Sun, 26 Feb 2023 15:30:00 +0000", "Sun, 26 Feb 2023 16:00:00 +0000",
"Sun, 26 Feb 2023 16:30:00 +0000", "Sun, 26 Feb 2023 17:00:00 +0000",
"Sun, 26 Feb 2023 17:30:00 +0000", "Sun, 26 Feb 2023 18:00:00 +0000"
]
Then
array.reject! { reject.next }
#=> ["Sat, 25 Feb 2023 10:30:00 +0000", "Sat, 25 Feb 2023 11:00:00 +0000",
# "Sat, 25 Feb 2023 11:30:00 +0000", "Sat, 25 Feb 2023 12:00:00 +0000",
# "Sat, 25 Feb 2023 12:30:00 +0000", "Sat, 25 Feb 2023 13:00:00 +0000",
# "Sat, 25 Feb 2023 13:30:00 +0000", "Sat, 25 Feb 2023 14:00:00 +0000",
# "Sat, 25 Feb 2023 14:30:00 +0000", "Sat, 25 Feb 2023 15:00:00 +0000",
# "Sat, 25 Feb 2023 15:30:00 +0000", "Sat, 25 Feb 2023 16:00:00 +0000",
# "Sat, 25 Feb 2023 16:30:00 +0000", "Sat, 25 Feb 2023 17:00:00 +0000",
# "Sat, 25 Feb 2023 17:30:00 +0000", "Sat, 25 Feb 2023 18:00:00 +0000",
# "Sun, 26 Feb 2023 10:30:00 +0000", "Sun, 26 Feb 2023 11:00:00 +0000",
# "Sun, 26 Feb 2023 11:30:00 +0000", "Sun, 26 Feb 2023 12:00:00 +0000",
# "Sun, 26 Feb 2023 12:30:00 +0000", "Sun, 26 Feb 2023 13:00:00 +0000",
# "Sun, 26 Feb 2023 13:30:00 +0000", "Sun, 26 Feb 2023 14:00:00 +0000",
# "Sun, 26 Feb 2023 14:30:00 +0000", "Sun, 26 Feb 2023 15:00:00 +0000",
# "Sun, 26 Feb 2023 15:30:00 +0000", "Sun, 26 Feb 2023 16:00:00 +0000",
# "Sun, 26 Feb 2023 16:30:00 +0000", "Sun, 26 Feb 2023 17:00:00 +0000",
# "Sun, 26 Feb 2023 17:30:00 +0000", "Sun, 26 Feb 2023 18:00:00 +0000"]
This clearly works for any number of days provided the first element of the array corresponds to 10:30
on the first day. The time associated with the last element of the array is not required to be 18:00
.
This calculation will be relatively fast as it does require that each DateTime
element be broken down into hours and minutes.
Upvotes: 2
Reputation: 502
This worked for me
w_start_time = (start_date - 1.minute).strftime('%k:%M:%S')
w_end_time = (start_date + 8.hours - 1.minute).strftime('%k:%M:%S')
hours = array.filter { |n| n.strftime('%k:%M:%S').between?(w_start_time, w_end_time) }
Upvotes: 0
Reputation: 57
Maybe you should try this :
array = array.reject { |date|
(date.hour < 10 || (date.hour == 10 && date.min < 30)) ||
(date.hour >= 18)
}
Upvotes: 0