1515(* ==== RFC822 ==== *)
1616type rfc822 = string
1717
18- let months = [| " Jan" ; " Feb" ; " Mar" ; " Apr" ; " May" ; " Jun" ;
18+ let months = [| " Jan" ; " Feb" ; " Mar" ; " Apr" ; " May" ; " Jun" ;
1919 " Jul" ; " Aug" ; " Sep" ; " Oct" ; " Nov" ; " Dec" |]
2020let days = [| " Sun" ; " Mon" ; " Tue" ; " Wed" ; " Thu" ; " Fri" ; " Sat" |]
2121
@@ -30,9 +30,11 @@ let rfc822_to_string x = x
3030
3131(* ==== ISO8601/RFC3339 ==== *)
3232
33- type print_type = PrintLocal | PrintUTC
33+ type print_timezone = Empty | TZ of string
3434(* we must store the print_type with iso8601 to handle the case where the local time zone is UTC *)
35- type iso8601 = Ptime .date * Ptime .time * print_type
35+ type iso8601 = Ptime .date * Ptime .time * print_timezone
36+
37+ let utc = TZ " Z"
3638
3739let of_dt print_type dt = let (date, time) = dt in (date, time, print_type)
3840let to_dt (date , time , _ ) = (date, time)
@@ -57,23 +59,22 @@ let best_effort_iso8601_to_rfc3339 x =
5759 match tz with
5860 | None | Some "" ->
5961 (* the caller didn't specify a tz. we must try to add one so that ptime can at least attempt to parse *)
60- (Printf. sprintf " %sZ" x, PrintLocal )
61- | Some _ ->
62- (* the caller specified a tz. we assume it's UTC because we don't accept anything else *)
63- (x, PrintUTC )
62+ (Printf. sprintf " %sZ" x, Empty )
63+ | Some tz ->
64+ (x, TZ tz)
6465
6566let of_string x =
66- let (rfc3339, print_type ) = best_effort_iso8601_to_rfc3339 x in
67+ let (rfc3339, print_timezone ) = best_effort_iso8601_to_rfc3339 x in
6768 match Ptime. of_rfc3339 rfc3339 |> Ptime. rfc3339_error_to_msg with
6869 | Error (`Msg e ) -> invalid_arg (Printf. sprintf " date.ml:of_string: %s" x)
6970 | Ok (t , tz , _ ) -> match tz with
70- | None | Some 0 -> Ptime. to_date_time t |> of_dt print_type
71+ | None | Some 0 -> Ptime. to_date_time t |> of_dt print_timezone
7172 | Some _ -> invalid_arg (Printf. sprintf " date.ml:of_string: %s" x)
7273
7374let to_string ((y ,mon ,d ), ((h ,min ,s ), _ ), print_type ) =
7475 match print_type with
75- | PrintUTC -> Printf. sprintf " %04i%02i%02iT%02i:%02i:%02iZ " y mon d h min s
76- | PrintLocal -> Printf. sprintf " %04i%02i%02iT%02i:%02i:%02i" y mon d h min s
76+ | TZ tz -> Printf. sprintf " %04i%02i%02iT%02i:%02i:%02i%s " y mon d h min s tz
77+ | Empty -> Printf. sprintf " %04i%02i%02iT%02i:%02i:%02i" y mon d h min s
7778
7879let to_ptime_t t =
7980 match to_dt t |> Ptime. of_date_time with
@@ -85,21 +86,13 @@ let to_ptime_t t =
8586let of_float s =
8687 match Ptime. of_float_s s with
8788 | None -> invalid_arg (Printf. sprintf " date.ml:of_float: %f" s)
88- | Some t -> Ptime. to_date_time t |> of_dt PrintUTC
89-
90- (* Convert tm in UTC back into calendar time x (using offset between above
91- UTC and localtime fns to determine offset between UTC and localtime, then
92- correcting for this)
93- *)
94- let to_float t =
95- let (_, _, print_type) = t in
96- match print_type with
97- | PrintLocal -> invalid_arg " date.ml:to_float: expected utc"
98- | PrintUTC -> to_ptime_t t |> Ptime. to_float_s
89+ | Some t -> Ptime. to_date_time t |> of_dt utc
90+
91+ let to_float t = to_ptime_t t |> Ptime. to_float_s
9992
10093let _localtime current_tz_offset t =
10194 let tz_offset_s = current_tz_offset |> Option. value ~default: 0 in
102- let localtime = t |> Ptime. to_date_time ~tz_offset_s |> of_dt PrintLocal in
95+ let localtime = t |> Ptime. to_date_time ~tz_offset_s |> of_dt Empty in
10396 let (_, (_, localtime_offset), _) = localtime in
10497 if localtime_offset <> tz_offset_s then
10598 invalid_arg (
0 commit comments