(*
 * Implementation of date2str.
 *
 * Given a correct calendar triple (day, month, year), return a proper English
 * date. For example: (1, 2, 2011) returns "February 1st, 2011".
 *
 * The suffix of the day number is not related to the actual month, so "February
 * 31st, 2011" can be generated. However, there is no reason to implement error
 * checking to prevent returning unvalid day/month combinations (not part of the
 * assignment). Note: the assigment clearly states that a correct calendar
 * triple is the input of date2str.
 *
 * This implementation does check for invalid day numbers or invalid month
 * numbers. The exception Hell will be raised for these invalid integers.
 *)
exception Hell

(*
 * Given a day number, return the day number followed by its English suffix. For
 * example, this will return ``1st'' for day 1, ``23rd'' for day 23 and ``12th'
 * for day 12. If the day number is negative or the day number is not between 1
 * and 31 (inclusive), Hell will be raised.
 *)
let day_with_suffix day =
    match day with
      1 | 21 | 31                  -> (string_of_int day) ^ "st"
    | 2 | 22                       -> (string_of_int day) ^ "nd"
    | 3 | 23                       -> (string_of_int day) ^ "rd"
    | _ when (day > 0 && day < 32) -> (string_of_int day) ^ "th"
    | _                            -> raise Hell
;;

(*
 * Return the English name of a month number (a number between 1 and 12,
 * inclusive). If the month number is not defined, Hell will be raised.
 *)
let month_name month =
    match month with
      1  -> "January"
    | 2  -> "February"
    | 3  -> "March"
    | 4  -> "April"
    | 5  -> "May"
    | 6  -> "June"
    | 7  -> "July"
    | 8  -> "August"
    | 9  -> "September"
    | 10 -> "October"
    | 11 -> "November"
    | 12 -> "December"
    | _  -> raise Hell
;;

let date2str day month year =
    Printf.sprintf "%s %s, %d" (month_name month) (day_with_suffix day) year
;;

(* correct date2str input: *)
print_string (date2str 2 2 2011);;
(* expected a raised Hell exception: *)
print_string (date2str (-2) 2 2011);;
