在F#中将字符串转换为System.DateTime

时间:2011-02-09 20:13:50

标签: date f#

如果我从命令行获取一个字符串,它看起来像这样:

'1-1-2011'

如何将该字符串转换为F#中的DateTime对象?

3 个答案:

答案 0 :(得分:22)

根据您的具体需要,.NET的DateTime类有几种静态方法可以将字符串转换为DateTime个实例,这些方法是DateTime.ParseDateTime.ParseExact和{{1和他们的几个重载。

@ 7sharp9演示了执行日期解析的最基本方法,直接调用DateTime.TryParse方法。但是F#中的事情变得有趣的是DateTime.Parse。如果解析失败,DateTime.TryParse将抛出异常,DateTime.Parse的最简单重载具有签名DateTime.TryParse,它将返回解析是否成功将string * byref<DateTime> -> bool参数设置为已解析如果为true,则为date,否则为默认值(在这种情况下为byref)。但是,在F#中使用它的语法很麻烦(实际上它并不适合任何.NET语言),因此F#语言的设计具有一个特殊的功能,允许像@Thomas Petricek指出的那样更好的调用约定。进行。

但即使是F#(bool,result)返回类型模式也不理想。大多数情况下,如果解析失败,则不需要默认值。 null的更好的签名是DateTime.TryParse。幸运的是,我们可以根据需要轻松扩展string -> option<DateTime>

DateTime

我们使用上面的扩展名如下:

type System.DateTime with 
    static member TryParseOption str =
        match DateTime.TryParse str with
        | true, r -> Some(r)
        | _ -> None

这与F#约定更为一致(例如match System.DateTime.TryParseOption "11/11/11" with | Some r -> stdout.WriteLine r | None -> stdout.WriteLine "none" )。但即使这样也可以“变得更好”。请注意我们如何匹配try解析的结果。使用部分活动模式(当然!),我们可以包装整个类的try parses并将匹配移动到匹配大小写以获得更大的灵活性。采取以下

List.tryFind

使用这些,我们可以编写一个简洁的小控制台应用程序:

open System
let (|DateTime|_|) str =
    match DateTime.TryParse str with
    | true, dt -> Some(dt)
    | _ -> None

let (|Int|_|) str =
    match Int32.TryParse str with
    | true, num -> Some(num)
    | _ -> None

let (|Float|_|) str =
    match Double.TryParse str with
    | true, num -> Some(num)
    | _ -> None

要注意的关键是嵌套匹配,其中let rec loop() = stdout.WriteLine " Please select an option: 1) Parse something 2) Exit " match stdin.ReadLine() with | Int 1 -> stdout.WriteLine "Enter something to parse: " match stdin.ReadLine() with | Int num -> stdout.WriteLine("Successfully parsed int: {0}", num) | Float num -> stdout.WriteLine("Successfully parsed float: {0}", num) | DateTime dt -> stdout.WriteLine("Successfully parsed DateTime: {0}", dt) | _ -> stdout.WriteLine "Parse Failed!" loop() | Int 2 -> stdout.WriteLine "Now exiting" | _ -> stdout.WriteLine "Invalid option, please try again" loop() IntFloat在同一个匹配表达式中执行try分析。

这些活动模式还有其他简洁的应用,例如,我们可以简洁地同时过滤和映射日期字符串列表

DateTime

答案 1 :(得分:11)

你可以这样做:

let dateTime = System.DateTime.Parse "1-1-2011"

答案 2 :(得分:11)

为7sharp9写的内容添加一个好东西,如果你还想处理失败,你可以写:

match System.DateTime.TryParse "1-1-2011" with
| true, date -> printfn "Success: %A" date
| false, _ -> printfn "Failed!"

这一点并不明显,因为TryParse方法的最后一个参数有byref<DateTime>(在C#中使用out),但是F#允许你调用方法像这样。