2010-09-15 12 views
5

Ja próbuje napisać funkcję, która generuje listę DateTimes wykorzystaniem składni prądotwórcze:F # generator daterange?

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 
     } 

ale generator („nast”) blok nie analizuje poprawnie. Chce czasu. Chociaż składnia generatora wydaje się idealna dla tego, co chcę zrobić, jest raczej nieintuicyjna dla niczego oprócz dwóch liczb.

  1. Czy można użyć składni generatora do utworzenia zakresu datodymków?
  2. czy istnieje lepszy sposób, aby myśleć o tym, jak utworzyć zakres niż napisałem (czyli „w” klauzuli)
+0

Format dat uniemożliwia odczytanie pozostałej części tego pytania. Poważnie, moje oczy podlewają. – Kendrick

+0

Nie do końca rozumiem. Jaki jest problem z formatem daty? –

Odpowiedz

5

arithemetic różnica między dwoma obiektami DateTime w .NET jest zawsze TimeSpan , to twój pierwszy problem. A gdybyś miał TimeSpan, to nie zaimplementowałby IEnumerable <>, więc nie może być użyty jako sekwencja. Możesz napisać własną ekspresję sekwencji, choć:

let rec dates (fromDate:System.DateTime) (toDate:System.DateTime) = seq { 
      if fromDate <= toDate then 
       yield fromDate 
       yield! dates (fromDate.AddDays(1.0)) toDate 
      } 

go używać do tworzenia sekwencji ze wszystkimi datami w zakresie, a następnie filtrować wyniki:

let result = dates startDate endDate |> Seq.filter (fun dt -> IsBusinessDate(dt)) 
11

Jeśli TimeSpan miał statyczny Zero własność, możesz zrobić coś takiego, jak startDate .. TimeSpan(1,0,0,0) .. endDate. Mimo że tak nie jest, możesz utworzyć opakowanie, które zrobi to samo:

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 
     }