根据设置的TimeSpans列表映射x个DateTimes

时间:2014-01-20 16:17:46

标签: c# linq datetime f# sequence

我正在尝试构建一个DateTimes序列,其中X个元素的长度可以追溯到时间,但只会落在某些TimeSpans上。这些TimeSpans是计算2个范围和提供的步长间隔之间的有效TimeSpans的结果。我首先使用以下方法计算此TimeSpans列表:

let timeSpans (rangeBottom: TimeSpan) (rangeTop: TimeSpan) (step: TimeSpan) =
    let isInsideRange (timeStamp: TimeSpan) =
        timeStamp >= rangeBottom && timeStamp < rangeTop

    let validTimes = list<TimeSpan>.Empty

    let rec checkTime (timeStamp:TimeSpan) (times: list<TimeSpan>) =
        if (isInsideRange(timeStamp)) then
            checkTime (timeStamp + step) (list.Cons(timeStamp, times))
        else
            list.Cons(rangeTop, times)
    checkTime rangeBottom validTimes

因此,给定rangeBottom为10AM,rangeTop为11AM,步长为12分钟,我将生成一个包含值[11:00:00; 10:48:00; 10:36:00; 10:24:00; 10:12:00; 10:00:00]的有效TimeSpans列表

现在,给定一个DateTime作为我的起点,我想从列表中最接近的TimeSpan开始,在周期性的时间内将其映射到我的TimeSpans列表中。

因此,如果我的注意点是今天的10:50,而我正在寻找8个值,那么我想要构建的结果序列是today 10:48, today 10:36, today 10:24, today 10:12, today 10:00, yesterday 11:00, yesterday 10:48, yesterday 10:36

我正在疯狂地试图周期性地重复使用TimeSpans以防止倒退,有人能指出我正确的方向吗?我的代码在F#中,但是如果有人能够理解这个问题并帮助我在C#中使用LINQ解决它,我很乐意将其转换过来。

2 个答案:

答案 0 :(得分:2)

我认为这就是你想要的。

repeat功能会将您的时间和开始日期转换为Seq DateTime的永不停止的Seq.skipWhile,然后您可以Seq.takelet times = timeSpans (TimeSpan.FromHours(10.)) (TimeSpan.FromHours(11.)) (TimeSpan.FromMinutes(12.)) let startDate = DateTime.Today.AddHours(10.).AddMinutes(50.) let rec repeat (date:DateTime) times = seq { yield! times |> Seq.map (fun t -> date.Date.Add(t)); yield! repeat (date.AddDays(-1.0)) times } times |> repeat startDate |> Seq.skipWhile (fun dt -> dt > startDate) |> Seq.take 8 |> Seq.toArray 获取正确的起点和项目数。

{{1}}

答案 1 :(得分:1)

这样的事情可能有用。

let times : seq<TimeSpan> = ... //computed using your function
let timesRepeating = seq { while true do yield! times }
let dates = seq<DateTime> = ... //your list of dates
let datesRepeating = 
  seq { for date in dates do
          for _ in times do
            yield date }

Seq.zip datesRepeating timesRepeating
|> Seq.map (fun (date, time) -> date.Add(time))