How to sort a list of string‑based dates in Ruby

1 Answer

0 votes
require "date"

#
# Program goal:
# -------------
# Sort a list of date strings in the format "YYYY-MM-DD".
#
# Approach:
#   1. Parse each string into a Date object using Date.strptime.
#   2. Sort using Ruby’s built-in Array#sort (O(n log n)).
#   3. Convert back to strings and print results.
#
# Architecture notes:
# -------------------
# - Parsing is isolated in a dedicated function for clarity and testability.
# - Sorting uses Array#sort, which is stable and efficient.
# - Error handling: invalid formats are detected and reported.
# - Edge cases: malformed strings, invalid ranges, leap years.
# - Performance: Date parsing is fast; sorting is O(n log n).
# - Memory: minimal; only an array of small objects.
# - Security: avoids unsafe parsing; uses strict format matching.
#

#
# Parse a date string into a Date object.
# Returns the Date or raises an exception with a clear message.
#
def parse_date(s)
  begin
    Date.strptime(s, "%Y-%m-%d")
  rescue ArgumentError
    raise "Invalid date: #{s}"
  end
end

#
# Sort a list of date strings.
# Returns a new sorted array; does not mutate the input.
#
def sort_dates(dates)
  parsed = []

  # Parse all dates; fail fast on invalid input.
  dates.each do |s|
    parsed << parse_date(s)
  end

  # Sort using natural Date ordering.
  parsed.sort.map { |d| d.strftime("%Y-%m-%d") }
end

#
# Helper to print a list of strings.
#
def print_list(list)
  list.each { |s| puts "  #{s}" }
end

#
# Helper to run a named test case.
#
def run_test(name, dates)
  puts "\n=== #{name} ==="
  begin
    sorted = sort_dates(dates)
    print_list(sorted)
  rescue => e
    puts "Error: #{e}"
  end
end

#
# Main program with multiple test cases.
#
puts "Ruby Date Sorting Demo"

# Basic chronological order
run_test("Basic chronological order", [
  "2024-01-05",
  "2023-12-31",
  "2024-01-01",
  "2022-07-15"
])

# Already sorted input
run_test("Already sorted input", [
  "2020-01-01",
  "2020-01-02",
  "2020-01-03"
])

# Leap year edge cases
run_test("Leap year edge cases", [
  "2020-02-29",
  "2019-02-28",
  "2021-03-01"
])

# Invalid date detection
run_test("Invalid date detection", [
  "2024-13-01",   # invalid month
  "2024-02-30",   # invalid day
  "not-a-date"    # malformed
])


#
# run:
#
# Ruby Date Sorting Demo
# 
# === Basic chronological order ===
#   2022-07-15
#   2023-12-31
#   2024-01-01
#   2024-01-05
# 
# === Already sorted input ===
# ERROR!
#   2020-01-01
#   2020-01-02
#   2020-01-03
# 
# === Leap year edge cases ===
#   2019-02-28
#   2020-02-29
#   2021-03-01
# 
# === Invalid date detection ===
# Error: Invalid date: 2024-13-01
# 

 



answered Sep 23 by avibootz
...