如果我从命令行获取一个字符串,它看起来像这样:
'1-1-2011'
如何将该字符串转换为F#中的DateTime对象?
答案 0 :(得分:22)
根据您的具体需要,.NET的DateTime类有几种静态方法可以将字符串转换为DateTime
个实例,这些方法是DateTime.Parse
,DateTime.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()
,Int
,Float
在同一个匹配表达式中执行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#允许你调用方法像这样。