package timere

  1. Overview
  2. Docs

Source file ISO8601.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
open Date_time_components

let to_date_time s : (Time.Date_time'.t, string) result =
  let open MParser in
  let open Parser_components in
  let two_digit_nat_zero =
    pair digit digit
    >>= fun (c1, c2) -> return (int_of_string (Printf.sprintf "%c%c" c1 c2))
  in
  let hm_p =
    choice
      [
        attempt
          (two_digit_nat_zero
           >>= fun hour ->
           optional (char ':')
           >> two_digit_nat_zero
           >>= fun minute -> return (hour, minute));
        (two_digit_nat_zero >>= fun hour -> return (hour, 0));
      ]
  in
  let hms_p =
    choice
      [
        attempt
          (two_digit_nat_zero
           >>= fun hour ->
           optional (char ':')
           >> two_digit_nat_zero
           >>= fun minute ->
           optional (char ':')
           >> two_digit_nat_zero
           >>= fun second -> return (hour, minute, second));
        (hm_p |>> fun (hour, minute) -> (hour, minute, 0));
      ]
  in
  let offset_p =
    char 'Z'
    >>$ 0
        <|> (char '+'
             >>$ 1
                 <|> (char '-' >>$ -1)
             >>= fun mult ->
             hm_p
             |>> fun (hour, minute) ->
             Duration.make ~hours:hour ~minutes:minute ()
             |> Duration.to_seconds
             |> Int64.to_int
             |> CCInt.mul mult)
  in
  let p =
    nat_zero
    >>= fun year ->
    char '-'
    >> two_digit_nat_zero
    >>= fun month ->
    match month_of_human_int month with
    | None -> fail "Invalid month"
    | Some month -> (
        char '-'
        >> two_digit_nat_zero
        >>= fun day ->
        optional (char 'T')
        >> hms_p
        >>= fun (hour, minute, second) ->
        offset_p
        >>= fun offset ->
        match
          Time.Date_time'.make_precise ~year ~month ~day ~hour ~minute ~second
            ~tz_offset_s:offset ()
        with
        | None -> fail "Invalid date time"
        | Some x -> return x)
  in
  parse_string p s () |> result_of_mparser_result