[OCaml] Mobile-friendly clone of cgit.
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