使用F#解析日期

时间:2012-04-30 16:52:08

标签: f# parsec fparsec

是否有一些'日期解析器'库可以用于日期FParsec对字符串的作用?

也就是说,您要么指定规则,要么匹配它们以识别提供的模式。


相反,是否有基于某些解析规则生成日期的库? 我们的想法是为用户提供“实时”完成,以指导他进行有效的未来fparsec匹配。

(生成解析的这个问题在僻静的解析圈中有名称吗?)

1 个答案:

答案 0 :(得分:8)

您可以定义一种简单的域特定语言(DSL)来表达这些规则。与“解析器”对应的类型实际上只是一个采用日期并返回布尔值的函数:

type DateClassifier = DC of (DateTime -> bool)

您可以轻松定义一些简单的功能:

// Succeeds when the date is wednesday
let wednesday = DC (fun dt -> dt.DayOfWeek = DayOfWeek.Wednesday)

// Succeeds if the date is after specified limit
let after limit = DC (fun dt -> dt > limit)

// Succeeds if the day is the specified value
let day d = DC (fun dt -> dt.Day = d)

// Takes two date classifiers and succeeds if either of them succeeds
let (<|>) (DC f) (DC g) = (fun dt -> f dt || g dt)

// Takes two date classifiers and succeeds if both of them succeed
let (<&>) (DC f) (DC g) = (fun dt -> f dt && g dt)

要指定你的条件 - “在本月5日之后的下一个星期三” - 你需要一个助手,它可以在第5天之后的任何一天产生成功的功能,这可以这样做(这有点效率低,但它是使用现有基元的组合,这很好):

let afterDay d = 
  [ for n in d + 1 .. 31 -> day n ] |> Seq.reduce (<|>)

您的规范(或“解析器”)只会在您描述的那天成功:

after DateTime.Now (wednesday <&> afterDay 5)