datetime - Parsing date and time with FParsec -


within simple query language i'd recognize date , time literals, preferably without using delimiters. example,

creationdate = 2013-05-13 5:30 pm 

i use combinator detect basic syntax (e.g., yyyy-mm-dd hh:mm tt), needs passed datetime.tryparse full validation.

a few questions:

  • is there combinator "post processing" parser result, e.g., pstring "1/2/2000" |> (fun s -> try ok(datetime.parse s) _ -> fail("not date"))
  • is possible apply predicate string (as satisfy char)?
  • is there better approach parsing date/time?

update

using guvante's , stephan's examples, came this:

let datetimeliteral =   let date sep = pipe5 pint32 sep pint32 sep pint32 (fun _ b _ c -> a, b, c)   let time =      (pint32 .>>. (skipchar ':' >>. pint32)) .>>.        (opt (stringcireturn " am" false <|> stringcireturn " pm" true))   (date (pstring "/") <|> date (pstring "-")) .>>.      (opt (skipchar ' ' >>. time)) .>> ws     >>=? (fun ((a, b, c), tt) ->       let y, m, d = if > 12 a, b, c else c, a, b       let h, n =         match tt         | some((h, n), tt) ->           match tt           | true -> (match h 12 -> h | _ -> h + 12), n           | false -> (match h 12 -> h - 12 | _ -> h), n           | none -> h, n         | none -> 0, 0       try preturn (system.datetime(y, m, d, h, n, 0)) |>> datetime        _ -> fail "invalid date/time format") 

you can build custom combinator or parser validates parsed input.

if want use combinators ("haskell-style"), use

let pdatestring = pstring "1/2/2000"  let pdate1 =      pdatestring      >>= fun str ->                        try preturn (system.datetime.parse(str))                           _ -> fail "date format error" 

as guvante proposed.

if want avoid construction temporary parsers (see preturn ... , pfail ... above), can let function accept second parameter , directly return reply values:

let pdate2 =      pdatestring      >>= fun str stream ->                        try reply(system.datetime.parse(str))                           _ -> reply(error, messageerror "date format error") 

if want error location @ beginning of malformed date string, replace >>= >>=?. note has consequences error recovery.

if want have full control, can write parser using lower level api, starting basic version following:

let pdate3 =      fun stream ->         let reply = pdatestring stream         if reply.status = ok                     try reply(system.datetime.parse(reply.result))                            _ -> reply(error, messageerror "date format error")         else            reply(reply.status, reply.error) 

this last version allow replace pdatestring parser code directly accesses charstream interface, give additional flexibility or performance.


Comments

Popular posts from this blog

php - cannot display multiple markers in google maps v3 from traceroute result -

c# - DetailsView in ASP.Net - How to add another column on the side/add a control in each row? -

javascript - firefox memory leak -