将字符串从格式字符串转换为 Core.Time.t
Converting strings to Core.Time.t from format string
我必须将 %d/%m/%Y %H:%M:%S
形式的字符串转换为 Time.t。是否有与日历的 Printer.Time.from_fstring
功能等效的核心?
基本版
据我所知Core
库中没有这样的函数。您可以使用 scanf
:
轻松实现
open Core.Std
let of_parts d m y hr min sec =
let time_of_day = Time.Ofday.create ~hr ~min ~sec () in
let m = Month.of_int_exn m in
let date = Date.create_exn ~y ~m ~d in
Time.of_date_ofday date time_of_day ~zone:Time.Zone.utc
let strptime0 data =
Scanf.sscanf data "%d/%d/%d %d:%d:%d" of_parts
完整版
strptime0
是第一个近似值,它将解析具有固定格式的输入。实现一个真正的 strptime
函数并不难,它将接受格式。为此,我们需要执行以下步骤:
转换格式字符串
首先我们需要将格式字符串从strptime
语言转换为格式语言,例如转换%Y -> %4d
等,然后使用Scanf.format_from_string
获取实例format
对象。此函数的 return 值应该是一种格式,适用于 scanf,以及一个置换矩阵,编码为数组。
重新排列参数
您可以使用数组来指定元素的顺序:
(** [rearrage f p a0 a1 a2 a3 a4 a5] call function [f] with
provided arguments passed in the order specified by the
permutation [p]
The [i]th element of the permutation [p] specifies the subscript
of the [i]'th argument to function [f]. Effectively [f] is called
like this: $f a_{p[0]} ... a_{p[i]} ... a_{p[5]}$ *)
let rearrange f arr a1 a2 a3 a4 a5 a6 =
let args = [| a1; a2; a3; a4; a5; a6 |] in
f args.(arr.(0)) args.(arr.(1)) args.(arr.(2))
args.(arr.(3)) args.(arr.(4)) args.(arr.(5))
(这会很好用,如果我们用整数表示所有部分,一次
我们将引入浮点参数(对于 %S
我们需要将参数提升为我们自己的编号类型)。
粘在一起
所以最后,你会得到这样的东西(你仍然需要填写存根)
(* d m y hr min sec *)
let canonical_format = format_of_string "%d%d%d%d%d%d"
(* this is a stub, that doesn't support rearrangment
and works incorrectly for most of inputs *)
let fmt_of_time p = function
| 'm' | 'Y' | 'H' | 'M' | 'S' -> 'd'
| x -> x
let transform_format fmt =
let p = Array.init 6 ~f:ident in (* stub: identity permutation *)
let fmt = String.map fmt ~f:(fmt_of_time p) in
let fmt = Scanf.format_from_string fmt canonical_format in
p, fmt
let strptime data fmt =
let (p,fmt) = transform_format fmt in
let of_parts = rearrange of_parts p in
Scanf.sscanf data fmt of_parts
因此,我们可以执行以下操作:
# strptime "09/05/1945 12:04:32" "%d/%m/%Y %H:%M:%S";;
- : Core.Std.Time.t = 1945-05-09 08:04:32.000000-04:00
我必须将 %d/%m/%Y %H:%M:%S
形式的字符串转换为 Time.t。是否有与日历的 Printer.Time.from_fstring
功能等效的核心?
基本版
据我所知Core
库中没有这样的函数。您可以使用 scanf
:
open Core.Std
let of_parts d m y hr min sec =
let time_of_day = Time.Ofday.create ~hr ~min ~sec () in
let m = Month.of_int_exn m in
let date = Date.create_exn ~y ~m ~d in
Time.of_date_ofday date time_of_day ~zone:Time.Zone.utc
let strptime0 data =
Scanf.sscanf data "%d/%d/%d %d:%d:%d" of_parts
完整版
strptime0
是第一个近似值,它将解析具有固定格式的输入。实现一个真正的 strptime
函数并不难,它将接受格式。为此,我们需要执行以下步骤:
转换格式字符串
首先我们需要将格式字符串从strptime
语言转换为格式语言,例如转换%Y -> %4d
等,然后使用Scanf.format_from_string
获取实例format
对象。此函数的 return 值应该是一种格式,适用于 scanf,以及一个置换矩阵,编码为数组。
重新排列参数
您可以使用数组来指定元素的顺序:
(** [rearrage f p a0 a1 a2 a3 a4 a5] call function [f] with
provided arguments passed in the order specified by the
permutation [p]
The [i]th element of the permutation [p] specifies the subscript
of the [i]'th argument to function [f]. Effectively [f] is called
like this: $f a_{p[0]} ... a_{p[i]} ... a_{p[5]}$ *)
let rearrange f arr a1 a2 a3 a4 a5 a6 =
let args = [| a1; a2; a3; a4; a5; a6 |] in
f args.(arr.(0)) args.(arr.(1)) args.(arr.(2))
args.(arr.(3)) args.(arr.(4)) args.(arr.(5))
(这会很好用,如果我们用整数表示所有部分,一次
我们将引入浮点参数(对于 %S
我们需要将参数提升为我们自己的编号类型)。
粘在一起
所以最后,你会得到这样的东西(你仍然需要填写存根)
(* d m y hr min sec *)
let canonical_format = format_of_string "%d%d%d%d%d%d"
(* this is a stub, that doesn't support rearrangment
and works incorrectly for most of inputs *)
let fmt_of_time p = function
| 'm' | 'Y' | 'H' | 'M' | 'S' -> 'd'
| x -> x
let transform_format fmt =
let p = Array.init 6 ~f:ident in (* stub: identity permutation *)
let fmt = String.map fmt ~f:(fmt_of_time p) in
let fmt = Scanf.format_from_string fmt canonical_format in
p, fmt
let strptime data fmt =
let (p,fmt) = transform_format fmt in
let of_parts = rearrange of_parts p in
Scanf.sscanf data fmt of_parts
因此,我们可以执行以下操作:
# strptime "09/05/1945 12:04:32" "%d/%m/%Y %H:%M:%S";;
- : Core.Std.Time.t = 1945-05-09 08:04:32.000000-04:00