exception Bad_month_string of string exception Bad_date_string of string (* Convert date numbers to and from DD-MMM-YY string entry points: string_of_date date_of_string secs_from_years years_from_secs *) let string_of_date date = let months = [|"Jan";"Feb";"Mar";"Apr";"May";"Jun"; "Jul";"Aug";"Sep";"Oct";"Nov";"Dec"|] and tm = Unix.gmtime date in ((Printf.sprintf "%2d" tm.Unix.tm_mday) ^ "-" ^ months.(tm.Unix.tm_mon) ^ "-" ^ (Printf.sprintf "%02d" (tm.Unix.tm_year mod 100))) let date_of_string date = (* I should just encode the months here and be done with it *) let date_re1 = Str.regexp ("^[ \t\n]*\\([0-9]+\\)" ^ (* dd-mmm-yy *) "[ \t\n-/]*\\([a-zA-Z][a-zA-Z][a-zA-Z]\\)" ^ "[ \t\n-/]*\\([0-9][0-9]+\\)$") and date_re2 = Str.regexp ("^[ \t\n]*\\([0-9]+\\)" ^ (* mm-dd-yy *) "[ \t\n-/]*\\([0-9]+\\)" ^ "[ \t\n-/]*\\([0-9]+\\)$") and date_re3 = Str.regexp ("^[ \t\n]*$") (* Right now *) and int_of_monthname string = match string with "Jan" -> 0 | "Feb" -> 1 | "Mar" -> 2 | "Apr" -> 3 | "May" -> 4 | "Jun" -> 5 | "Jul" -> 6 | "Aug" -> 7 | "Sep" -> 8 | "Oct" -> 9 | "Nov" -> 10 | "Dec" -> 11 | _ -> raise (Bad_month_string string) and mkdate mday mon year = match Unix.mktime { Unix.tm_sec = 0; Unix.tm_min = 0; Unix.tm_hour = 12; Unix.tm_mday = mday; Unix.tm_mon = mon; Unix.tm_wday = 0; (* Don't care? *) Unix.tm_year = year; Unix.tm_yday = 0; (* Don't care? *) Unix.tm_isdst = false } with secs, tm -> secs and int_of_year year = let year = int_of_string year in if (year < 50) then year + 100 else if (year > 1000) then year - 1900 else year in (* Convert to number of years since 1900. Assume 00 means 2000, 49 means 2049, 50 means 1950, 99 means 1999. Anything over 1000 is used as-is. *) if (Str.string_match date_re3 date 0) then (Unix.gettimeofday ()) else if (Str.string_match date_re1 date 0) then (mkdate (int_of_string (Str.matched_group 1 date)) (int_of_monthname (Str.matched_group 2 date)) (int_of_year (Str.matched_group 3 date))) else if (Str.string_match date_re2 date 0) then (mkdate (int_of_string (Str.matched_group 2 date)) ((int_of_string (Str.matched_group 1 date)) - 1) (int_of_year (Str.matched_group 3 date))) else raise (Bad_date_string date) let secs_from_years years = years *. 31557600.0 let years_from_secs secs = secs /. 31557600.0 let year_of_date date = int_of_float ((years_from_secs date) +. 1970.0)