View raw

1 (** Formatting Git dates for display. 2 3 Git records a commit date as a Unix timestamp plus the offset of the zone 4 the author was in. Relative and short forms drop that offset and use the 5 server's local zone, which is what a reader scanning a list wants; the 6 detailed form preserves it, because on a single commit the author's own 7 wall-clock time is the meaningful one. *) 8 9 let relative_time (date, _) = 10 let seconds = Unix.time () -. Int64.to_float date |> int_of_float in 11 let minutes = seconds / 60 in 12 let hours = minutes / 60 in 13 let days = hours / 24 in 14 let months = days / 30 in 15 let years = months / 12 in 16 let quantity value singular = 17 Printf.sprintf "%d %s%s ago" value singular (if value = 1 then "" else "s") 18 in 19 match seconds with 20 | s when s < 60 -> "just now" 21 | _ when minutes < 60 -> quantity minutes "minute" 22 | _ when hours < 24 -> quantity hours "hour" 23 | _ when days < 30 -> quantity days "day" 24 | _ when months < 12 -> quantity months "month" 25 | _ -> quantity years "year" 26 27 (** Minute precision, server-local, for dense listings. *) 28 let short_time (date, _) = 29 let tm = date |> Int64.to_float |> Unix.localtime in 30 Printf.sprintf "%04d-%02d-%02d %02d:%02d" (tm.tm_year + 1900) (tm.tm_mon + 1) 31 tm.tm_mday tm.tm_hour tm.tm_min 32 33 (** Second precision in the recorded zone. Returns the machine-readable form for 34 a [datetime] attribute alongside the human-readable form. *) 35 let exact_time (date, timezone) = 36 let offset_seconds, suffix = 37 match timezone with 38 | None -> (0, "Z") 39 | Some (offset : Git.User.tz_offset) -> 40 let direction = match offset.sign with `Plus -> 1 | `Minus -> -1 in 41 let seconds = direction * ((offset.hours * 60) + offset.minutes) * 60 in 42 let sign = match offset.sign with `Plus -> "+" | `Minus -> "-" in 43 (seconds, Printf.sprintf "%s%02d:%02d" sign offset.hours offset.minutes) 44 in 45 let adjusted = Int64.add date (Int64.of_int offset_seconds) in 46 let tm = adjusted |> Int64.to_float |> Unix.gmtime in 47 let day = 48 Printf.sprintf "%04d-%02d-%02d" (tm.tm_year + 1900) (tm.tm_mon + 1) 49 tm.tm_mday 50 in 51 let clock = Printf.sprintf "%02d:%02d:%02d" tm.tm_hour tm.tm_min tm.tm_sec in 52 ( Printf.sprintf "%sT%s%s" day clock suffix, 53 Printf.sprintf "%s %s %s" day clock suffix ) 54