从格式字符串将字符串转换为Core.Time.t

时间:2015-09-22 09:41:10

标签: ocaml ocaml-core

我必须将%d/%m/%Y %H:%M:%S形式的字符串转换为Time.t.是否有Core等效的Calendar Printer.Time.from_fstring函数?

1 个答案:

答案 0 :(得分:1)

基本版

据我所知,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获取{{1}的实例1}}对象。此函数的返回值应该是适合scanf的格式,以及编码为数组的置换矩阵。

重新排列参数

您可以使用数组指定元素的顺序:

format

(如果我们用一次整数表示所有部分,这将正常工作     我们将引入浮点参数(对于(** [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