Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save gato-omega/f4ebf86658b7c82c0e8b3f7faeedd38f to your computer and use it in GitHub Desktop.
Save gato-omega/f4ebf86658b7c82c0e8b3f7faeedd38f to your computer and use it in GitHub Desktop.
Create a "compact" human readable string output for enumerating multiple times/datetimes (modify according to your formatting preference/situation)
# For use with Time/DateTime objects
#
# Give it an array of Time objects and receive the following output as a String
# Examples:
#
# Sat/Sun 9:30am, 10am | Mon 9:30am, 10am, 11am
# Sat 9:30am, 10am | Sun 10am | Mon 9:30am, 10am, 11am
# Sat/Sun 9:30am
# Sat 10am | Sun 9:30am
# Sat/Sun/Mon 10am
# require 'active_support/core_ext/time/zones.rb' # If you want to test with Rails / ActiveSupport::TimeWithZone
def compact_format_for_multiple_times(times)
times_grouped_by_day = times.sort.group_by{|time| time.strftime('%a')}
# {
# "Sat" => [
# [0] Sat, 07 Jul 2018 09:30:00 UTC +00:00,
# [1] Sat, 07 Jul 2018 10:00:00 UTC +00:00
# ],
# "Sun" => [
# [0] Sun, 08 Jul 2018 09:30:00 UTC +00:00,
# [1] Sun, 08 Jul 2018 10:00:00 UTC +00:00
# ],
# "Mon" => [
# [0] Mon, 09 Jul 2018 09:30:00 UTC +00:00,
# [1] Mon, 09 Jul 2018 10:00:00 UTC +00:00,
# [2] Mon, 09 Jul 2018 11:00:00 UTC +00:00
# ]
# }
times_of_day_grouped_by_day = Hash[times_grouped_by_day.map{|k,v| [k, v.sort.map{|time| time.strftime('%k:%M%P').strip}]}]
# {
# "Sat" => [
# [0] "9:30am",
# [1] "10:00am"
# ],
# "Sun" => [
# [0] "9:30am",
# [1] "10:00am"
# ],
# "Mon" => [
# [0] "9:30am",
# [1] "10:00am",
# [2] "11:00am"
# ]
# }
regrouped_days_with_same_times_of_day = Hash[times_of_day_grouped_by_day.group_by{|k,v| v}.map{|k,v| [k,v.map{|day_and_time_pair| day_and_time_pair.first}]}].invert
# {
# [ "Sat", "Sun" ] => [
# [0] "9:30am",
# [1] "10:00am"
# ],
# [ "Mon" ] => [
# [0] "9:30am",
# [1] "10:00am",
# [2] "11:00am"
# ]
# }
# Sat/Sun 9:30am, 10am | Mon 9:30am, 10am, 11am
formatted_output = regrouped_days_with_same_times_of_day.map{|days, times| [days.join('/'), times.join(', ')].join(' ')}.join(' | ').gsub(':00', '')
end
def test
a_9_30 = Time.new(2018, 7, 7, 9, 30, 0) # Time.zone.parse('2018-07-07 09:30:00') # Sat 09:30am
a_10 = Time.new(2018, 7, 7, 10, 0, 0) # Time.zone.parse('2018-07-07 10:00:00') # Sat 10:00am
b_9_30 = Time.new(2018, 7, 8, 9, 30, 0) # Time.zone.parse('2018-07-08 09:30:00') # Sun 09:30am
b_10 = Time.new(2018, 7, 8, 10, 0, 0) # Time.zone.parse('2018-07-08 10:00:00') # Sun 10:00am
c_9_30 = Time.new(2018, 7, 9, 9, 30, 0) # Time.zone.parse('2018-07-09 09:30:00') # Mon 09:30am
c_10 = Time.new(2018, 7, 9, 10, 0, 0) # Time.zone.parse('2018-07-09 10:00:00') # Mon 10:00am
c_11 = Time.new(2018, 7, 9, 11, 0, 0) # Time.zone.parse('2018-07-09 11:00:00') # Mon 11:00am
times_1 = [a_9_30, a_10, b_9_30, b_10, c_9_30, c_10, c_11]
times_2 = [a_9_30, a_10, b_10, c_9_30, c_10, c_11]
times_3 = [a_9_30, b_9_30]
times_4 = [a_10, b_9_30]
times_5 = [a_10, b_10, c_10]
puts compact_format_for_multiple_times times_1
puts compact_format_for_multiple_times times_2
puts compact_format_for_multiple_times times_3
puts compact_format_for_multiple_times times_4
puts compact_format_for_multiple_times times_5
end
test()
# You should get:
#
# Sat/Sun 9:30am, 10am | Mon 9:30am, 10am, 11am
# Sat 9:30am, 10am | Sun 10am | Mon 9:30am, 10am, 11am
# Sat/Sun 9:30am
# Sat 10am | Sun 9:30am
# Sat/Sun/Mon 10am
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment