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

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

javascript - firefox memory leak -

Trying to import CSV file to a SQL Server database using asp.net and c# - can't find what I'm missing -