我正在尝试使用生成器语法编写一个生成DateTimes列表的函数:
let dateRange =
let endDate = System.DateTime.Parse("6/1/2010")
let startDate = System.DateTime.Parse("3/1/2010")
seq {
for date in startDate..endDate do
if MyDateClass.IsBusinessDay(date) then yield date
}
但生成器('seq')块无法正确解析。它需要一个时间跨度。虽然生成器语法看起来非常适合我想做的事情,但对于除了两个数字之外的任何东西都是非直观的。
答案 0 :(得分:11)
如果TimeSpan
具有静态Zero
属性,那么您可以执行startDate .. TimeSpan(1,0,0,0) .. endDate
之类的操作。即使它没有,你可以创建一个包装器来做同样的事情:
open System
type TimeSpanWrapper = { timeSpan : TimeSpan } with
static member (+)(d:DateTime, tw) = d + tw.timeSpan
static member Zero = { timeSpan = TimeSpan(0L) }
let dateRange =
let endDate = System.DateTime.Parse("6/1/2010")
let startDate = System.DateTime.Parse("5/1/2010")
let oneDay = { timeSpan = System.TimeSpan(1,0,0,0) }
seq {
for date in startDate .. oneDay .. endDate do
if MyDateClass.IsBusinessDay(date) then yield date
}
答案 1 :(得分:5)
.NET中两个DateTime对象之间的arithemetic差异始终是TimeSpan,这是您的第一个问题。如果您有TimeSpan,它将不会实现IEnumerable<>,因此不能用作序列。但是,您可以编写自己的序列表达式:
let rec dates (fromDate:System.DateTime) (toDate:System.DateTime) = seq {
if fromDate <= toDate then
yield fromDate
yield! dates (fromDate.AddDays(1.0)) toDate
}
您可以使用它来创建一个包含范围内所有日期的序列,然后过滤结果:
let result = dates startDate endDate |> Seq.filter (fun dt -> IsBusinessDate(dt))